ALGORITHM ANALYSE:bfs+位运算 //每个方格里的棋子只有两种状态,因此可用0,1表示,而整个棋盘则可以表示为一个十六位的二进制整数 //若要对某个位置做翻转操作,可对整数进行异或操作,棋盘上每个位置上的翻转二进制数是可以预先求得的 //bfs对每个位置进行翻转,因为整个棋盘只有十六个位置,因此所有的状态是不超过2^16的,对每个扩展进行标记后可以避免重复的状态 //因为状态是有限的,因此队列可以为空 CODE: #include <stdio.h> #include <stdlib.h> #include <string.h> int myqueue[500000],step[500000],qback=0,qfront=0; int flag[500000],turn[20]; int main() { int i,j,ini=0; char ch; char str[5][6]; for(i=15;i>=0;i--) { turn[i]=(1<<i); if(i<12) turn[i]+=(1<<(i+4)); if(i%4!=3) turn[i]+=(1<<(i+1)); if(i%4!=0) turn[i]+=(1<<(i-1)); if(i>3) turn[i]+=(1<<(i-4)); } for(i=0;i<4;i++) scanf("%s",str[i]); for(i=0;i<4;i++) for(j=0;j<4;j++) if(str[i][j]=='b') ini+=(1<<(15-(4*i)-j)); memset(flag,0,70000); flag[ini]=1; myqueue[0]=ini; step[0]=0; qback++; while(qfront!=qback) { if(myqueue[qfront]==0 || myqueue[qfront]==65535) { printf("%d",step[qfront]); return 0; } else { int temp; for(i=15;i>=0;i--) { temp=myqueue[qfront]^turn[i]; if(flag[temp]==0) { flag[temp]=1; myqueue[qback]=temp; step[qback]=step[qfront]+1; qback++; } } } qfront++; } printf("Impossible"); return 0; } //这道题目的精髓在于位运算,通过异或符号快速度的对相关位置进行取反操作,使得队列中的元素只是一个整数