这个题是说有一个4*4的矩阵,里面的每个格子,不是白色就是黑色,w表示白色,b表示黑色。每一次可以改变3-5中颜色,即以一个点为中心,改变时,这个点和它四个方向的点的颜色都要改变!最后,要达到所有格子的颜色都相同,输入最小步数!
刚开始看这个题的时候,就再想,这一点是一个dbs,但是总是不知道要怎么去判重!如果用数字模拟的话就要想八数码那样每次都要重新开辟数组并复制,很麻烦并且不好处理!
就这样,这个判重问题一直想了一个星期,最后,还是陈洪国跟我说可以用二进制来做这个题!然后才逐渐明白了!
下面是我提交的代码:
#include<iostream>
#include<math.h>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
char word[4][4];
char s[20];
bool vis[65535];
int n;
int dir[16]={51200,58368,29184,12544,35968,20032,10016,4880,2248,1252,626,305,140,78,39,19};
struct node
{
int status;
int steps;
}node1,node2;
queue <struct node> q;
void init()
{
memset(vis,false,sizeof(vis));
while(!q.empty())
q.pop();
}
int trans(char word[])
{
int len=strlen(word);
int k=0,x=0;
for(int i=len-1;i>=0;i--)
{
x=x+(word[i]-'0')*int(pow(double(2),k));
k++;
}
return x;
}
void bfs()
{
init();
node1.status=n;
node1.steps=0;
q.push(node1);
vis[node1.status]=true;
while(!q.empty())
{
node1=q.front();
q.pop();
for(int i=0;i<16;i++)
{
node2.status=node1.status^dir[i];
node2.steps=node1.steps+1;
if(vis[node2.status]) continue;
if(node2.status==0||node2.status==65535)
{
cout<<node2.steps<<endl;
return ;
}
else
{
q.push(node2);
vis[node2.status]=true;
}
}
}
if(node2.status!=0&&node2.status!=65535) cout<<"Impossible"<<endl;
}
int main()
{
int k=0;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
cin>>word[i][j];
if(word[i][j]=='w') s[k++]='0';
else s[k++]='1';
}
getchar();
}
n=trans(s);
// cout<<n<<endl;
if(n==0||n==65535) cout<<0<<endl;
else bfs();
return 0;
}