~题目链接~
http://poj.org/problem?id=2965
输入
-+-- ---- ---- -+--
结果
6 1 1 1 3 1 4 4 1 4 3 4 4
1.BFS+位运算
自己写了一半天异或的代码,又长又不实用,提交还TLE(此在代码有 已被注释,如果有大牛可以改出来,希望帮助);后跟人家学了一招,很方便。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #define maxm 65535+10 #define maxn 4 using namespace std; int ID[30] = {4383,8751,17487,34959,4593,8946,17652,35064,7953,12066,20292,36744,61713,61986,62532,63624}; int id=0,m=0,vis[1<<17]; struct node { int data,num,step; } cur; struct path { int x,pre; }p[maxm<<2]; void f(int n) { if(n) { f(p[n].pre); printf("%d %d ",4-p[n].x/4,4-p[n].x%4); } } void BFS() { int i; cur.data=id; cur.num=0; cur.step=0; p[1].pre=0; queue<node>Q; Q.push(cur); while(!Q.empty()) { if(Q.front().data==0) { printf("%d ",Q.front().step); f(Q.front().num); return; } for(i=15; i>=0; i--) { node a; //提交TLE的码码,有大牛在的话,求指教 /*int j; a.data=Q.front().data^(1<<i);//此位点翻转 j=i; while(j<12)//此位点列翻转 { a.data^=1<<(j+4); j+=4; } j=i; while(j>=4) { a.data^=1<<(j-4); j-=4; } j=i; while(j%4)//此位点行翻转 { a.data^=1<<(j-1); j--; } j=i; while((j+1)%4) { a.data^=1<<(j+1); j++; }//上面写的异或的代码很长而且提交TLE*/ a.data=Q.front().data^ID[i];//异或 if(!vis[a.data]) { a.num=++m; a.step=Q.front().step+1; p[m].pre=Q.front().num;//存点,以便路径回溯 p[m].x=i; Q.push(a); vis[a.data]=1; } } Q.pop(); } } int main() { char s[maxn]; for(int i=0; i<maxn; i++) { scanf("%s",s); for(int j=0; j<maxn; j++) { id*=2; if(s[j]=='+') { id+=1; } } } BFS(); return 0; }
2.在POJ的讨论中看到大牛的一种高效方法之后写的代码
~大牛解题链接~ http://poj.org/showmessage?message_id=156561
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #define maxn 4 using namespace std; int flag[maxn][maxn]; struct node { int x,y; }N; int main() { char s[maxn][maxn]; memset(flag,true,sizeof(flag)); for(int i=0; i<maxn; i++) scanf("%s",s[i]); for(int i=0; i<maxn; i++) for(int j=0; j<maxn; j++) if(s[i][j]=='+') { flag[i][j]=!flag[i][j]; for(int k=0; k<maxn; k++) { flag[k][j]=!flag[k][j]; flag[i][k]=!flag[i][k]; } } int num=0; queue<struct node>Q; for(int i=0; i<maxn; i++) for(int j=0; j<maxn; j++) if(!flag[i][j]) { N.x=i; N.y=j; Q.push(N); num++; } printf("%d ",num); while(!Q.empty()) { printf("%d %d ",Q.front().x+1,Q.front().y+1); Q.pop(); } return 0; }