您的位置:首页 > 其它

POJ1753-FlipGame

2012-08-28 12:01 218 查看
第一种方法:先枚举第一行的16种情况,然后依次翻转第2、3、4行分别使上一行为同一色,然后判断第四行,若仍为同一色,则比较翻转次数;否则Impossible.

Problem: 1753User: wjinkun
Memory: 352KTime: 16MS
Language: GCCResult: Accepted
#include <stdio.h>
#include <string.h>

int piece[4][4],temp_piece[4][4];

void flip(int i,int j)
{
temp_piece[i][j]=!temp_piece[i][j];

if(i-1>=0)
temp_piece[i-1][j]=!temp_piece[i-1][j];

if(i+1<=3)
temp_piece[i+1][j]=!temp_piece[i+1][j];

if(j-1>=0)
temp_piece[i][j-1]=!temp_piece[i][j-1];

if(j+1<=3)
temp_piece[i][j+1]=!temp_piece[i][j+1];
}

int main()
{
int i,j,k,min=17,n;

for(i=0; i<4; i++)               //b1w0
{
for(j=0; j<4; j++)
if(getchar()=='b')
piece[i][j]=1;
else
piece[i][j]=0;

getchar();
}

//全翻至白
for(i=0; i<16; i++)          //第一行2^4=16种情况
{
memcpy(temp_piece,piece,sizeof(piece));
n=0;

for(j=0; j<4; j++)
if((i&(1<<j))>>j)       //第一行第j个翻转
{
flip(0,j);
n++;
}

for(j=1; j<4; j++)         //翻转第2.3.4行分别使上一行为都为白
for(k=0; k<4; k++)
if(temp_piece[j-1][k])
{
flip(j,k);
n++;
}

for(j=0; j<4; j++)       //检查第4行是否都为白
if(temp_piece[3][j])
{
n=17;
break;
}

if(n<min)
min=n;
}

//全翻至黑
for(i=0; i<16; i++)
{
memcpy(temp_piece,piece,sizeof(piece));
n=0;

for(j=0; j<4; j++)
if((i&(1<<j))>>j)
{
flip(0,j);
n++;
}

for(j=1; j<4; j++)
for(k=0; k<4; k++)
if(!temp_piece[j-1][k])
{
flip(j,k);
n++;
}

for(j=0; j<4; j++)
if(!temp_piece[3][j])
{
n=17;
break;
}

if(n<min)
min=n;
}

if(n!=17)
printf("%d\n",min);
else
printf("%s","Impossible\n");

return 0;
}


第二种方法是看了别人的思路后写的,枚举+bfs:用unsigned short记录棋子的2^16=65536种情况,将初始状态入队列,再出队列判断是否是0或65535(同一色),若是则输出,否则将由该状态翻转1次的入队列,依次类推。关键减少时间的步骤是要记录最大的棋子,比如a状态由翻转2,5两个棋子得到,那么a的下一次翻转只需从6开始,前面的情况一定出现过,因此需记录5,减少重复。

Problem: 1753User: wjinkun
Memory: 588KTime: 16MS
Language: GCCResult: Accepted
#include <stdio.h>
unsigned short queue[65536][2];   //[0]记录状态,[1]记录下一次起始位置
unsigned short step[65536];       //步数

int main()
{
int rear=1,top=0,i,j,temp;

for(i=0; i<4; i++)               //b1w0
{
for(j=0; j<4; j++)
if(getchar()=='b')
queue[0][0]|=1<<(i*4+j);

getchar();
}

while(rear>top)
{
if(queue[top][0]==0||queue[top][0]==65535)
{
printf("%d\n",step[queue[top][0]]);
return 0;
}
else
{
for(i=queue[top][1]; i<16; i++)
{
temp=queue[top][0];
temp^=1<<i;

if(i%4!=0)
temp^=1<<(i-1);

if(i%4!=3)
temp^=1<<(i+1);

if(i-4>=0)
temp^=1<<(i-4);

if(i+4<16)
temp^=1<<(i+4);

queue[rear][0]=temp;
queue[rear++][1]=i+1;
step[temp]=step[queue[top][0]]+1;
}

top++;
}
}

printf("%s\n","Impossible\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: