pku1077 Eight
A*
Memory:6384K Time:79MS
太烂了,估计是hash太肿...有空再来优化
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define MAXN 362881
int fac[9]={40320,5040,720,120,24,6,2,1,1};
int stseq[9],edseq[9]={1,2,3,4,5,6,7,8,0},stkey,edkey;
int g[MAXN],f[MAXN],mk[MAXN],pre[MAXN];
char op[MAXN];
int h(int seq[9]){
int i,ret=0;
for(i=0;i<9;i++)
ret+=abs(seq[i]-edseq[i]);
return ret;
//return 0;
}
int getkey(int seq[9]){
int nsn,sum=0;
for(int i=0;i<9;i++){
nsn=0;
for(int j=i+1;j<9;j++)
if(seq[i]>seq[j])
nsn++;
sum+=nsn*fac[i];
}
return sum;
}
void getseq(int key,int* &seq,int &pos){//key of "876543210" = 40319 < 40320
int i,j,k;
for(i=0;i<9;i++){
seq[i]=key/fac[i];
key%=fac[i];
}
bool used[9]={0};
used[seq[0]]=true;
if(seq[0]==0)
pos=0;
for(i=1;i<9;i++){
j=0;
for(k=0;j<seq[i] && k<9;k++)
if(!used[k])
j++;
while(used[k])
k++;
seq[i]=k;
used[k]=true;
if(seq[i]==0)
pos=i;
}
}
class CP{
public:
int operator()(int t1,int t2){
return f[t1]>f[t2];
}
};
void output(int key){
int *seq,i;
string ans="";
seq=new int[9];
for(i=g[key]-1;i>=0;i--){
ans+=op[key];
key=pre[key];
}
for(i=ans.length()-1;i>=0;i--)
cout<<ans[i];
cout<<endl;
}
int astar(){
int curkey,*curseq,pos,nkey;
curseq=new int[9];
memset(mk,0,sizeof(mk));
priority_queue< int, vector<int> ,CP> qu;
stkey=getkey(stseq);
mk[stkey]=1;
g[stkey]=0;
f[stkey]=g[stkey]+h(stseq);
qu.push(stkey);
f[362880]=-1;
edkey=getkey(edseq);
while(!qu.empty()){
curkey=qu.top();
qu.pop();
mk[curkey]=2;
if(curkey==edkey){
output(curkey);
return g[curkey];
}
getseq(curkey,curseq,pos);
if(pos>=3){
swap(curseq[pos],curseq[pos-3]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='u';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='u';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos-3]);
}
if(pos<6){
swap(curseq[pos],curseq[pos+3]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='d';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='d';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos+3]);
}
if(pos%3!=2){
swap(curseq[pos],curseq[pos+1]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='r';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='r';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos+1]);
}
if(pos%3!=0){
swap(curseq[pos],curseq[pos-1]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='l';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='l';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos-1]);
}
}
return -1;
}
int main(){
int i;
char ch;
for(i=0;i<9;i++){
cin>>ch;
if(ch=='x')
stseq[i]=0;
else
stseq[i]=ch-'0';
}
if(astar()==-1)
cout<<"unsolvable\n";
return 0;
}
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define MAXN 362881
int fac[9]={40320,5040,720,120,24,6,2,1,1};
int stseq[9],edseq[9]={1,2,3,4,5,6,7,8,0},stkey,edkey;
int g[MAXN],f[MAXN],mk[MAXN],pre[MAXN];
char op[MAXN];
int h(int seq[9]){
int i,ret=0;
for(i=0;i<9;i++)
ret+=abs(seq[i]-edseq[i]);
return ret;
//return 0;
}
int getkey(int seq[9]){
int nsn,sum=0;
for(int i=0;i<9;i++){
nsn=0;
for(int j=i+1;j<9;j++)
if(seq[i]>seq[j])
nsn++;
sum+=nsn*fac[i];
}
return sum;
}
void getseq(int key,int* &seq,int &pos){//key of "876543210" = 40319 < 40320
int i,j,k;
for(i=0;i<9;i++){
seq[i]=key/fac[i];
key%=fac[i];
}
bool used[9]={0};
used[seq[0]]=true;
if(seq[0]==0)
pos=0;
for(i=1;i<9;i++){
j=0;
for(k=0;j<seq[i] && k<9;k++)
if(!used[k])
j++;
while(used[k])
k++;
seq[i]=k;
used[k]=true;
if(seq[i]==0)
pos=i;
}
}
class CP{
public:
int operator()(int t1,int t2){
return f[t1]>f[t2];
}
};
void output(int key){
int *seq,i;
string ans="";
seq=new int[9];
for(i=g[key]-1;i>=0;i--){
ans+=op[key];
key=pre[key];
}
for(i=ans.length()-1;i>=0;i--)
cout<<ans[i];
cout<<endl;
}
int astar(){
int curkey,*curseq,pos,nkey;
curseq=new int[9];
memset(mk,0,sizeof(mk));
priority_queue< int, vector<int> ,CP> qu;
stkey=getkey(stseq);
mk[stkey]=1;
g[stkey]=0;
f[stkey]=g[stkey]+h(stseq);
qu.push(stkey);
f[362880]=-1;
edkey=getkey(edseq);
while(!qu.empty()){
curkey=qu.top();
qu.pop();
mk[curkey]=2;
if(curkey==edkey){
output(curkey);
return g[curkey];
}
getseq(curkey,curseq,pos);
if(pos>=3){
swap(curseq[pos],curseq[pos-3]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='u';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='u';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos-3]);
}
if(pos<6){
swap(curseq[pos],curseq[pos+3]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='d';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='d';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos+3]);
}
if(pos%3!=2){
swap(curseq[pos],curseq[pos+1]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='r';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='r';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos+1]);
}
if(pos%3!=0){
swap(curseq[pos],curseq[pos-1]);
nkey=getkey(curseq);
if(mk[nkey]==0){
mk[nkey]=1;
pre[nkey]=curkey;
op[nkey]='l';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(nkey);
}
else if(mk[nkey]==1){
if(g[curkey]+1<g[nkey]){
pre[nkey]=curkey;
op[nkey]='l';
g[nkey]=g[curkey]+1;
f[nkey]=g[nkey]+h(curseq);
qu.push(362880);
qu.pop();
}
}
swap(curseq[pos],curseq[pos-1]);
}
}
return -1;
}
int main(){
int i;
char ch;
for(i=0;i<9;i++){
cin>>ch;
if(ch=='x')
stseq[i]=0;
else
stseq[i]=ch-'0';
}
if(astar()==-1)
cout<<"unsolvable\n";
return 0;
}