题目大意:一个冰箱有16个开关,呈方形分布(4*4矩阵),“+”表示关闭,“-”表示开着,当所有的开关为“-”时冰箱才能打开。当去翻转一个开关时,在该开关所在列和行的所有开关都要翻转,即开变关,关变开。问至少需要多少次才能打开冰箱。
#include<iostream>
using namespace std;
int queue[65536];
int visited[65536];
int step[65536];
int temp,count=0;
int front =0,rear=1;
int row,col;
struct remember
{
int pisition;
int parents;
}Link[65536];
int PB(int s,int i)
{
int mstate=s;
int j,k;
row=i/4;
col=i%4;
for (j=0;j<4;j++)
{
mstate ^= 1<<(row*4 + j);
}
for (k=0;k<4;k++)
{
mstate ^= 1<<(k*4 +col);
}
mstate ^= 1<<(row*4 + col);
return mstate;
}
void output(int now)
{
if (now==temp)
{
return;
}
output(Link[now].parents);
cout<<Link[now].pisition/4+1<<" "<<Link[now].pisition%4+1<<endl;
}
int BFS(int state)
{
int depth=0;
int s,i;
queue[front]=state;
visited[state]=1;
if (state ==0)
{
return 0;
}
Link[state].parents=state;
while (front!=rear)
{
s=queue[front];
front ++;
for (i=0;i<16;i++)
{
state=PB(s,i);
if (visited[state]==0)
{
queue[rear]=state;
visited[state]=1;
step[state] =step[s]+1;
Link[state].pisition=i;
Link[state].parents=s;
if (state == 0)
{
return 1;
}
rear++;
}
}
}
return 0;
}
int main(int argc,char *argv[])
{
char str[17];
int i,k;
int state = 0;
memset(visited,0,sizeof(visited));
memset(queue,0,sizeof(queue));
memset(step,0,sizeof(step));
memset(Link,0,sizeof(Link));
i=0;
while (i<16)
{
cin>>str[i];
if (str[i]=='+')
{
state += 1<<i;
}
i++;
}
str[i]='\0';
temp=state;
k=BFS(state);
if (k==0)
{
cout<<0<<endl;
}
if (k==1)
{
cout<<step[0]<<endl;
}
output(0);
return 0;
}