思路:
这三个题是一个比一个令人纠结呀。
POJ-1077
爆搜可以过,94ms,注意不能用map就是了。
#include<iostream> #include<stack> #include<queue> #include<map> #include<cstring> using namespace std; const int maxn = 500086; const int inf = 2.1e9; const int mod = 1e9+7; const double eps = 1e-6; int ans=123456780; char mp[5][5]; int Head[maxn]; int viss[maxn]; int Next[maxn]; int tot; bool findd(int n) { int s=n%maxn; int k=Head[s]; while(k!=-1){ if(viss[k]==n){return true;} k=Next[k]; // cout<<k<<endl; } tot++; Next[tot]=Head[s]; viss[tot]=n; Head[s]=tot; return false; } int n=3; int a[10],k; int mypow(int b) { // int s=1; // for(int i=1;i<=b;i++){ // s*=a; // } // return s; if(b==0){return 1;} if(b==1){return 10;} if(b==2){return 100;} if(b==3){return 1000;} if(b==4){return 10000;} if(b==5){return 100000;} if(b==6){return 1000000;} if(b==7){return 10000000;} if(b==8){return 100000000;} // else if(b==9){return 1000000000;} } inline int cal() { int ans=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(mp[i][j]=='x'){ans*=10;} else{ans=ans*10+mp[i][j]-48;} } } return ans; } int pre[maxn]; char op[maxn]; inline int up(int num) { if(k<=3){return -1;} int t=k-3; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } inline int down(int num) { if(k>=7){return -1;} int t=k+3; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } inline int left(int num) { if(k==1||k==4||k==7){return -1;} int t=k-1; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } inline int right(int num) { if(k==3||k==6||k==9){return -1;} int t=k+1; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } void getf(int t) { for(int i=9;i>=1;i--){ a[i]=t%10; t/=10; if(a[i]==0){k=i;} } } int bfs() { queue<int>q; queue<int>qq; q.push(cal()); qq.push(-1); int pos=1; int ah; int ss,num,t; while(!q.empty()){ num=q.front(); ss=qq.front(); qq.pop(); q.pop(); getf(num); t=up(num); if(t==ans){pre[pos]=ss;op[pos]='u';return pos;} if(t!=-1&&!findd(t)){ pre[pos]=ss; op[pos]='u'; q.push(t); qq.push(pos); pos++; } t=down(num); if(t==ans){pre[pos]=ss;op[pos]='d';return pos;} if(t!=-1&&!findd(t)){ pre[pos]=ss; op[pos]='d'; q.push(t); qq.push(pos); pos++; } t=left(num); if(t==ans){pre[pos]=ss;op[pos]='l';return pos;} if(t!=-1&&!findd(t)){ pre[pos]=ss; op[pos]='l'; q.push(t); qq.push(pos); pos++; } t=right(num); if(t==ans){pre[pos]=ss;op[pos]='r';return pos;} if(t!=-1&&!findd(t)){ pre[pos]=ss; op[pos]='r'; q.push(t); qq.push(pos); pos++; } } return -1; } int main() { ios::sync_with_stdio(false); // while(cin>>) memset(Head,-1,sizeof(Head)); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>mp[i][j]; } } if(cal()==ans){cout<<"lr"<<endl;return 0;} int k=bfs(); stack<char>sss; while(k>0){ sss.push(op[k]); k=pre[k]; } while(!sss.empty()){ cout<<sss.top(); sss.pop(); } cout<<endl; return 0; }
HDU -1043
预处理打表,注意要逆向。
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<cstdio> #include<cstring> #define fuck(x) /*cout<<#x<<" = "<<x<<endl;*/; #define ls (t<<1) #define rs ((t<<1)+1) using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 5000086; const int inf = 2.1e9; const ll Inf = 999999999999999999; const int mod = 1e9+7; const double eps = 1e-6; int anss=123456780; int fac[10]; void getfac() { fac[0]=1; for(int i=1;i<=9;i++){ fac[i]=fac[i-1]*i; } } int KT(int numi) { ll ans=0; int op[10]; int s=numi; for(int i=9;i>=1;i--){ op[i]=numi%10; // if(op[i]==0){op[i]=9;} numi/=10; } for(int i=1;i<=9;i++){ int sum=0; for(int j=i+1;j<=9;j++){ if(op[j]<op[i]){sum++;} } ans+=sum*fac[9-i]; } // if(ans+1==92307){cout<<"__"<<s<<endl;} return ans+1; } int a[15],k; void getf(int t) { for(int i=9;i>=1;i--){ a[i]=t%10; t/=10; if(a[i]==0){k=i;} } } int mypow(int b) { if(b==0){return 1;} if(b==1){return 10;} if(b==2){return 100;} if(b==3){return 1000;} if(b==4){return 10000;} if(b==5){return 100000;} if(b==6){return 1000000;} if(b==7){return 10000000;} if(b==8){return 100000000;} } int up(int num) { if(k<=3){return num;} int t=k-3; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int down(int num) { if(k>=7){return num;} int t=k+3; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int left(int num) { if(k==1||k==4||k==7){return num;} int t=k-1; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int right(int num) { if(k==3||k==6||k==9){return num;} int t=k+1; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int ans[maxn]; int ord[maxn]; char op[maxn]; struct node { int num,s; }; void bfs() { queue<node>q; q.push(node{anss,0}); int pos=1; node exa; int t,kt; ans[KT(anss)]=pos;pos++; while(!q.empty()){ exa=q.front(); q.pop(); int num=exa.num; getf(num); fuck(num) t=up(num); kt=KT(t); fuck(t) if(!ans[kt]){ // cout<<"_"<<endl; ans[kt]=pos;fuck(pos); fuck(exa.s); ord[pos]=exa.s; q.push(node{t,pos}); op[pos]='d'; pos++; } t=down(num); fuck(t) kt=KT(t); if(!ans[kt]){ // cout<<"_"<<endl; ans[kt]=pos; fuck(pos); fuck(exa.s); ord[pos]=exa.s; q.push(node{t,pos}); op[pos]='u'; pos++; } t=left(num); fuck(t) kt=KT(t); if(!ans[kt]){ // cout<<"_"<<endl; fuck(pos); fuck(exa.s); fuck(kt); ans[kt]=pos; ord[pos]=exa.s; q.push(node{t,pos}); op[pos]='r'; pos++; } t=right(num); fuck(t) kt=KT(t); if(!ans[kt]){ // cout<<"_"<<endl; ans[kt]=pos; fuck(pos); fuck(exa.s); ord[pos]=exa.s; q.push(node{t,pos}); op[pos]='l'; pos++; } } } char mp[10][10]; int main() { ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); getfac(); int hh=0;; bfs(); // for(int i=1;i<=100;i++){ // cout<<i<<": "<<ord[i]<< // } for(int i=1;i<=10;i++){ fuck(ord[i]); fuck(op[i]); } while(cin>>mp[1][1]){ for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ if(i==1&&j==1){continue;} cin>>mp[i][j]; } } int cnt=0; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ if(mp[i][j]=='x'){cnt*=10;} else{cnt=cnt*10+mp[i][j]-48;} } } // cout<<cnt<<endl; // cout<<KT(cnt)<<endl; int kk=ans[KT(cnt)]; if(kk==0){printf("unsolvable\n");} else{ while(kk){ printf("%c",op[kk]); // cout<<kk<<" "<<op[kk]<<endl; kk=ord[kk]; } printf("\n"); } } // system("pause"); return 0; }
HDU 3567
这个按顺序预处理,我曾试图使用优先队列,控制一下字典序,但是会超时,看其他的题解都没有这样做,于是我就直接跑,没有管这些了,当然在bfs的时候还是要按照dlru来进行搜索的。
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<cstdio> #include<cstring> #define fuck(x) cout<<#x<<" = "<<x<<endl; #define ls (t<<1) #define rs ((t<<1)+1) using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 4000086; const int inf = 2.1e9; const ll Inf = 999999999999999999; const int mod = 1e9+7; const double eps = 1e-6; int fac[15]; void getfac() { fac[0]=1; for(int i=1;i<=9;i++){ fac[i]=fac[i-1]*i; } } int mypow(int b) { if(b==0){return 1;} if(b==1){return 10;} if(b==2){return 100;} if(b==3){return 1000;} if(b==4){return 10000;} if(b==5){return 100000;} if(b==6){return 1000000;} if(b==7){return 10000000;} if(b==8){return 100000000;} } int a[100],k; int anss[10]={0,12345678,102345678,120345678 ,123045678,123405678,123450678 ,123456078,123456708,123456780}; int up(int num) { if(k<=3){return num;} int t=k-3; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int down(int num) { if(k>=7){return num;} int t=k+3; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int left(int num) { if(k==1||k==4||k==7){return num;} int t=k-1; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } int right(int num) { if(k==3||k==6||k==9){return num;} int t=k+1; num+=a[t]*mypow(9-k); num-=a[t]*mypow(9-t); return num; } void getf(int t) { for(int i=9;i>=1;i--){ a[i]=t%10; t/=10; if(a[i]==0){k=i;} } } int KT(int numi) { ll ans=0; int op[10]; int s=numi; for(int i=9;i>=1;i--){ op[i]=numi%10; numi/=10; } for(int i=1;i<=9;i++){ int sum=0; for(int j=i+1;j<=9;j++){ if(op[j]<op[i]){sum++;} } ans+=sum*fac[9-i]; } return ans+1; } int ans[10][maxn]; int pre[10][maxn]; char op[10][maxn]; struct node { int num,s; }; void bfs(int ind) { queue<node>q; q.push(node{anss[ind],0}); int pos=1; node exa; int t,kt; ans[ind][KT(anss[ind])]=pos;pos++; while(!q.empty()){ exa=q.front(); q.pop(); int num=exa.num; getf(num); t=down(num); kt=KT(t); if(!ans[ind][kt]){ ans[ind][kt]=pos; pre[ind][pos]=exa.s; q.push(node{t,pos}); op[ind][pos]='d'; pos++; } t=left(num); kt=KT(t); if(!ans[ind][kt]){ ans[ind][kt]=pos; pre[ind][pos]=exa.s; q.push(node{t,pos}); op[ind][pos]='l'; pos++; } t=right(num); kt=KT(t); if(!ans[ind][kt]){ ans[ind][kt]=pos; pre[ind][pos]=exa.s; q.push(node{t,pos}); op[ind][pos]='r'; pos++; } t=up(num); kt=KT(t); if(!ans[ind][kt]){ ans[ind][kt]=pos; pre[ind][pos]=exa.s; q.push(node{t,pos}); op[ind][pos]='u'; pos++; } } } char s1[15],s2[15]; int numm(char *ss) { int ans=0; for(int i=1;i<=9;i++){ if(ss[i]=='X'){ans*=10;} else ans=ans*10+ss[i]-48; } return ans; } int change() { int pos=0; for(int i=1;i<=9;i++){ if(s2[i]=='X'){pos=i;} } char temp[15]; strcpy(temp+1,s1+1); int v=0; for(int i=1;i<=9;i++){ if(s2[i]=='X'){continue;} v++; for(int j=1;j<=9;j++){ if(temp[j]==s2[i]){s1[j]=v+48;break;} } s2[i]=v+48; } return pos; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); getfac(); for(int i=1;i<=9;i++){ bfs(i); } int T; scanf("%d",&T); int cases=0; while(T--){ scanf("%s%s",s2+1,s1+1); cases++; printf("Case %d: ",cases); int j=change(); stack<char>q; int t1,t2; t1=numm(s1); int kk=ans[j][KT(t1)]; if(kk==1){printf("0\n\n");} else{ while(kk){ q.push(op[j][kk]); kk=pre[j][kk]; } printf("%d\n",q.size()); while(!q.empty()){ printf("%c",q.top()); q.pop(); } printf("\n"); } } return 0; }