翻牌,将所翻牌地所有相邻的排都翻一遍。
说明:1.翻两次回恢复原状。所以结果中没有重复数字。
2.所得结果和翻牌次序无关 如 121 <->211 <->2
3.初始即为全白www。。。,则要输出11;
4.我用一个整数保存的路径,因为结果最大为123456789
所以广度优先搜索,2^9 时间和空间复杂度大致均1024次内,所以也不用什么位操作什么的,直接就可以了。
我的疑问是为什么深度优先搜不行?一直wa,如果按照顺序1-9的搜,应该也是对的呀?
下附bfs ac的:
#include<stdio.h>
#include<cstring>
#include<queue>
using namespace std;
int N;
char s[10] , cp[10] , goal[10] = "wwwwwwwww";
int v[1025];
void opp(char & c){
if(c == 'w') c = 'b';
else if( c == 'b') c= 'w';
}
struct PAIR{
int rou;
char str[10];
};
queue<PAIR> q;
int toInt(){
int i = 0;
for(int k = 0; k < 9;k++)
i = i * 2 + ((s[k] == 'w') ? 1 : 0);
return i;
}
void invert(int i){
int k;
switch(i){
case 1: opp(s[0]);opp(s[1]);opp(s[3]);opp(s[4]);break;
case 2: for( k = 0; k < 6; k++) opp(s[k]);break;
case 3: opp(s[1]);opp(s[2]);opp(s[4]);opp(s[5]);break;
case 4: for( k = 0; k<7 ; k+=3)opp(s[k]);
for( k = 1; k<8 ; k+=3)opp(s[k]);break;
case 5: for( k = 0; k<9; k++)opp(s[k]);break;
case 6: for( k = 1; k<8 ; k+=3)opp(s[k]);
for( k = 2; k<9 ; k+=3)opp(s[k]);break;
case 7: opp(s[3]);opp(s[4]);opp(s[6]);opp(s[7]);break;
case 8: for( k = 3; k<9 ; k++)opp(s[k]);break;
case 9: opp(s[4]);opp(s[5]);opp(s[7]);opp(s[8]);break;
default: break;
}
}
int main(){
//freopen("in.txt", "r", stdin);
scanf("%d", &N);
while(N--){
while(!q.empty())q.pop();
scanf("%s", s);
memset(v, 0, sizeof(v));
int i , start, road = 11;
PAIR pr;
pr.rou = 0;
strcpy(pr.str , s);
q.push(pr);
while(!q.empty() && strcmp(s, goal)){
start = q.front().rou ;
strcpy(s, q.front().str);
q.pop();
for(i = start % 10 + 1; i<10; i++){
invert( i );
int tmp = toInt( );
if(v[tmp]){invert(i) ;continue;}
v[tmp] = 1;
pr.rou = start * 10 + i;
strcpy(pr.str , s);
q.push(pr);
if(! strcmp(s, goal)){road = pr.rou;break;}
invert(i);
}
}
printf("%d\n", road);
}
}