调了半天,还是TLE,看了网上的代码基本没有用bfs+哈希判重做的,要么是dfs要么压根不用哈希判重,难道说bfs+哈希注定过不了?
看了下程序只有算哈希函数的地方有一个25的循环比较累赘,别的地方循环不是很多,可是25位必须要循环才能算哈希函数额。。。
求解释。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int MAX=60003; int n,sx,sy,count,head[MAX],Next[MAX],que[MAX]; int dx[8]={-1,-2,-2,-1,1,2,2,1}; int dy[8]={-2,-1,1,2,2,1,-1,-2}; char chess[6][6],vis[MAX][26]; char target[26]="111110111100 110000100000"; int calhash(char arr[]) { int s=0; for (int i=0;i<25;i++) s=s*10+arr[i]; return (s & 0x7FFFFFFF)%MAX; //ensure s is positive } bool hasvisited(int s) { int h=calhash(vis[s]); int u=head[h]; while (u) { if (!strcmp(vis[u],vis[s])) return true; u=Next[u]; } Next[s]=head[h]; head[h]=s; return false; } void toArray(int s) { int p=0; for (int i=0;i<5;i++) for (int j=0;j<5;j++) vis[s][p++]=chess[i][j]; vis[s][p]='\0'; } void bfs() { int front=1,rear=2; que[0]=0; que[1]=sy*5+sx; toArray(1); count=-1; bool flag=0; hasvisited(1); while(front<rear) { count++; if (count==10) { cout<<"Unsolvable in less than 11 move(s)."<<endl; break; } int tmprear=rear; while(front<tmprear) { if (!strcmp(vis[front],target)) { cout<<"Solvable in "<<count<<" move(s)."<<endl; flag=1; break; } int loc=que[front]; int ox=loc%5; int oy=loc/5; for (int i=0;i<8;i++) { int nx=ox+dx[i]; int ny=oy+dy[i]; if (nx>=0&&nx<5&&ny>=0&&ny<5) { int nloc=ny*5+nx; memcpy(vis[rear],vis[front],sizeof(vis[front])); char tmpchar=vis[rear][loc]; vis[rear][loc]=vis[rear][nloc]; vis[rear][nloc]=tmpchar; if (!hasvisited(rear)) { que[rear++]=nloc; } } } front++; } if (flag) break; } } int main() { cin>>n; getchar(); while (n--) { for (int i=0;i<5;i++) { cin.getline(chess[i],6); for (int j=0;j<5;j++) { if (chess[i][j]==' ') {sx=j;sy=i;} } } memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); bfs(); } return 0; }