题目就不粘贴了。说的就是八数码的问题,纠结了好几天了,一开始用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;
}