您的位置:首页 > 其它

ZOJ 1066 Square Ice(POJ 1099)(找规律&模拟)

2011-04-14 12:09 656 查看
我觉得是我的RP回来了,在我被一个题卡了三四天之后,我的RP他回来了……

 

不扯了,说题意:就是说有张 n*n 个水分子组成的平面图,这些水分子的摆放有三种情况:两个H-O键成180度角,且分子横放(在数字矩阵中用 1 表示);两个H-O键成180度角,且分子竖放(在数字矩阵中用 -1 表示);两个H-O键成 90 度角,这种的摆放比较复杂,需要分境况讨论(数字矩阵中用 0 表示)。

 

它们摆放有一个基本原则,就是中学时我们学的化学常识了,每个 O 原子和两个 H 原子配对,配对过后的原子就不能再参与配对了。

 

同时,题目输出要求是第一行的 H 原子不在 O 原子上面,最后一行的 H 原子不在 O 原子下面(其实这样是为了简化问题的难度,这样的话这题就有规律可循了)。

 

看题时推荐看 poj 上的图,因为 zoj 上的图给的很纠结,一时半会看不出来……

 

我的思路哈,想了好久的说……

 

我们很容易发现,题目要求输出的图中如果先不管 H-O 键的话,也就是说光看 H 和 O 原子的话,它们的位置是有规律的,H 原子分两种,一种是从点(2,2)开始横,纵坐标分别以 4 递增,另一种是从点(4,4)开始横,纵坐标分别以 4 递增。而 O 原子的个数就是 n*n ,从(2,4)开始,以 4 递增。我们可以先画出一张没有 H-O 键的图来,然后在根据 数字矩阵中的值,给每一个 O 原子加上两个 H-O 键就可以了。

 

最后加上 H-O 键的时候,按 数字矩阵 分3种情况,1 和 -1 时,很好处理,关键是 0 的时候。仔细看题,有这么一句话: ……the sum of each row and column is 1  ……

就是这句了,解题点,根据 数字矩阵 中该行(或列)上 从开始到现在的点的数值和,可以判断,这个 H-O 键的方向:

上下:该列第一行到该行的数值和,0代表 H-O 在这个 O 原子下面,1是上。

左右:该行第一列到该列的数值和,0代表 H-O 在这个 O 原子左面,1是右。

 

好了,到此,这个题就没意思了,模拟吧,注意代码中的变量不要搞混的说……TAT……

 

#include<stdio.h>
#include<string.h>
#define N 60
int x,y,n;
char mat

;
struct node
{
int num,id;
int hang,lie;
}map

;
void init()
{
int i,j;
memset(mat,0,sizeof(mat));
for(i=1;i<=x;i++) //空格 和 '*'
{
for(j=1;j<=y;j++)
{
if(i==1 || i==x || j==1 || j==y) mat[i][j]='*';
else mat[i][j]=' ';
}
}
for(i=2;i<x;i=i+4) //H原子
{
for(j=2;j<y;j=j+4)
mat[i][j]='H';
}
for(i=4;i<x;i=i+4) //H原子
{
for(j=4;j<y;j=j+4)
mat[i][j]='H';
}
for(i=2;i<x;i=i+4) //O原子
{
for(j=4;j<y;j=j+4)
mat[i][j]='O';
}
}
void putmat()
{
int i,j;
for(i=1;i<=x;i++)
{
for(j=1;j<=y;j++)
printf("%c",mat[i][j]);
puts("");
}
}
int main()
{
int i,j,h,g,time=1;
while(scanf("%d",&n),n)
{
if(time>1)puts("");
memset(map,0,sizeof(map));
y=4*n+3, x=4*n-1;//x行数,y列数
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&map[i][j].num);
map[i][j].id=n*(i-1)+j;
map[i][j].hang=map[i][j].lie=map[i][j].num;
map[i][j].hang+=map[i][j-1].hang;
map[i][j].lie+=map[i-1][j].lie;
}
}

init();
int k=1;
for(i=1;i<=x;i++)
{
for(j=1;j<=y;j++)
{
if(mat[i][j]=='O')
{
int find=0;
for(h=1;h<=n;h++)
{
for(g=1;g<=n;g++)
if(map[h][g].id==k)
{
find=1,k++;break;
}
if(find)break;
}
if(map[h][g].num==1) mat[i][j-1]='-',mat[i][j+1]='-';
else if(map[h][g].num==-1) mat[i-1][j]='|',mat[i+1][j]='|';
else if(map[h][g].num==0)
{
if(map[h][g].hang==0) mat[i][j-1]='-';
else if(map[h][g].hang==1) mat[i][j+1]='-';
if(map[h][g].lie==0) mat[i+1][j]='|';
else if(map[h][g].lie==1) mat[i-1][j]='|';
}
}
}
}
printf("Case %d:/n/n",time++);
putmat();
}
return 0;
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struct each c