1048 Inverso

TAG 宽度优先搜索

 

明确几点:

1.每个操作最多出现一次。因为重复操作会抵消。

2.操作的次序对最后结果没有影响。

3.从初始状态变换到全白,跟从全白变换到初始状态的操作步骤是一致的。

 

所以

1.不必每次都搜索一次,预处理一次后,后面可以直接输出结果。

2.使操作步骤序号递增,且每个序号最多输出一次。

3.使用宽度优先搜索可以保证最后操作次数最少。

 

输入全白时要输出 11

我还以为不用输出,直接回车。。(╬▔ ω▔) 杯具。。又wa了几次。。

 

#include <stdio.h> #include <memory.h> const int N=512; const int trans[9]={ 0660, 0770, 0330, 0666, 0777, 0333, 066, 077, 033 }; struct node { int state,pre,step,method; }; int ans[N]; bool vis[N]; int cs; char grid[10]; node que[N]; void bfs(int st, int dep) { int head, tail; head=0; tail=1; que[0].state=0; que[0].pre=-1; que[0].step=0; que[0].method=9; vis[0]=true; ans[0]=0; while ( head < tail ) { for (int i=que[head].method-1; i>=0; --i) { int tmp=que[head].state ^ trans[i]; if ( !vis[tmp] ) { que[tail].state=tmp; que[tail].pre=head; que[tail].step=que[head].step+1; que[tail].method=i; ans[tmp]=tail; ++tail; vis[tmp]=true; } } ++head; } } void pre() { memset(vis, false, sizeof(vis) ); bfs(0,0); } void output(int idx) { char s[N+1]; int p=-1; while ( que[ idx ].pre!=-1 ) { s[++p]=que[idx].method+1+'0'; idx=que[idx].pre; } for (int i=0; i<=p; ++i) { printf("%c", s[i]); } printf("/n"); } int main(int argc, char *argv[]) { scanf("%d", &cs); pre(); while ( cs-- ) { scanf("%s", grid); int tmp=0; for (int i=0; i<9; ++i) { tmp=(tmp << 1)+ (grid[i]=='b'); } if ( tmp==0 ) { printf("11/n"); } else { output( ans[tmp] ); } } return 0; }

 

你可能感兴趣的:(c,struct,output)