题目就不粘贴了。说的就是八数码的问题,纠结了好几天了,一开始用map去做,然后TLE到让人呕吐;今天做的时候用到了康托展开,但是还是TLE,这就让人有点不愉快了,可是尼玛还是一直TLE啊!神啊!救命啊~~~纠结了一会后,把题目中所有的string 全部换成char,诶,尼玛居然就过了!我就呵呵了......
由此得出一个结论:stl 能不用就尽量不用,尽管它很方便,简洁。
有关于康托展开的内容,请戳:http://blog.csdn.net/morgan_xww/article/details/6275460
丑代码贴一发纪念下:
#include<map> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; struct edge{ int pose; char str[15]; }; edge p,v; char s[100]; int path[1000000],cont,k; int x[]={1,-1,-3,3}; int an[]={1,1,2,6,24,120,720,5040,40320}; int Cantor(char *s){ int ret=0; for(int i=0;i<9;i++){ int tot=0; for(int j=i;j<9;j++) if(s[i]>s[j]) tot++; ret+=tot*an[9-i-1]; }return ret; } bool judge(int i,int pose){ if(i==0&&!((pose+1)%3)) return false; if(i==1&&!(pose%3)) return false; if(i==2&&pose<3) return false; if(i==3&&pose>5) return false; return true; } void print(edge s){ int cont=Cantor(s.str); if(path[cont]==520) return ; swap(s.str[s.pose],s.str[s.pose-x[path[cont]]]); s.pose-=x[path[cont]]; print(s); if(path[cont]==0) printf("r"); if(path[cont]==1) printf("l"); if(path[cont]==2) printf("u"); if(path[cont]==3) printf("d"); } void bfs(){ memset(path,-1,sizeof(path)); queue<edge>q; while(q.size()) q.pop(); cont=Cantor(p.str); path[cont]=520; q.push(p); while(q.size()){ p=q.front(); q.pop(); for(int i=0;i<4;i++){ if(judge(i,p.pose)){ v.pose=p.pose+x[i]; strcpy(v.str,p.str); swap(v.str[v.pose],v.str[p.pose]); cont=Cantor(v.str); if(path[cont]==-1){ path[cont]=i; q.push(v); if(cont==0){ print(v); return ; } } } } }printf("unsolvable"); } int main(){ gets(s); k=0; for(int i=0;i<strlen(s);i++){ if(s[i]=='x') s[i]='9'; if(s[i]>='1'&&s[i]<='9') p.str[k++]=s[i]; if(s[i]=='9') p.pose=k-1; } bfs(); printf("\n"); return 0; }