hdu 1430 魔板
来源:互联网 发布:java系统架构师 编辑:程序博客网 时间:2024/06/05 07:14
刚开始不知道有康托展开,一筹莫展,查了一下大神题解。看到说要用康托展开,遂跑去学。
康托展开:http://blog.csdn.net/zhongkeli/article/details/6966805
学完写爆搜,结果TLE。冥思苦想半天,发现所有的魔版初态其实都可以用“12346578”来替换。即s->e可以等量变换成ss->se。所以我们只用bfs遍历“12345678”经过A,B,C三种变化后的所有可能解,然后将每种解存储下来,就可以直接取了。
花了两个小时写了这个代码。贴上去发现也不对。
#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<queue>using namespace std;const int N=8;struct node{ string s; string step;};string b,c;queue<node> q;node start;string a[50000];int compress(int k,string s){ int sum=0; for(int i=k+1;i<N;i++) { if(s[i]<s[k]) sum++; } return sum;}int fac(int ans){ if(ans==7) return 5040; if(ans==6) return 720; if(ans==5) return 120; if(ans==4) return 24; if(ans==3) return 6; if(ans==2) return 2; if(ans==1) return 1; if(ans==0) return 0;}int kt(string s){ int sum=0; int ans=7; for(int i=0;i<N;i++) { sum+=compress(i,s)*fac(ans); ans--; } return sum;}string Fun(string ss,int n){ int l,r; if(n==0) { l=7; r=0; while(l>r) { swap(ss[l],ss[r]); l--; r++; } return ss; } if(n==2) { swap(ss[6],ss[2]); swap(ss[1],ss[2]); swap(ss[6],ss[5]); return ss; } if(n==1) { for(int i=3;i>0;i--) swap(ss[i],ss[i-1]); for(int i=4;i<7;i++) swap(ss[i],ss[i+1]); //cout<<ss<<endl; return ss; }}void bfs(){ while(!q.empty()) { node hd=q.front(); q.pop(); node t=hd; int num; for(int i=0;i<3;i++) { t=hd; t.step.push_back(i+'A'); //cout<<t.step<<endl; string ss=hd.s; ss=Fun(ss,i); //用i+'A'方案对ss变形 //cout<<ss<<endl; num=kt(ss); if(!a[num].size()&&num!=0) { a[num]=t.step; t.s=ss; q.push(t); } } }}void ys(){ int k=0; int j=1; string bb=b,cc=c; while(j<=8) { for(int i=0;i<N;i++) { if(b[i]==j+'0') { //cout<<j<<endl; bb[k++]=b[i]; cc[k-1]=c[i]; j++; } if(j==9) { //cout<<bb<<endl; //cout<<cc<<endl; b=bb; c=cc; return ; } } }}int main(){ freopen("in.txt","r",stdin); memset(a,NULL,sizeof(a)); start.s="12345678"; int num=kt(start.s); cout<<num<<endl; a[num]=start.step; q.push(start); bfs(); while(cin>>b) { getchar(); cin>>c; ys(); //cout<<b<<endl; //cout<<c<<endl; //cout<<kt(c); cout<<a[kt(c)]<<endl; } return 0;}
找了老半天,是子函数ys发生错误。原来是我对于替换理解错了。
比如:13467852->16347852应该转变为12345678->14235678。
而我却认为应该变为12345678->12635478。
将代码改成这样
#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<queue>using namespace std;const int Nstruct node{string s;string step;};ing b,c;queue<node> q;node start;string a[50000];int compress(int k,string s){ int sum=0; for(int i=k+1;i<N;i++) { if(s[i]<s[k]) sum++; } return sum;}int fac(int ans){ if(ans==7) return 5040; if(ans==6) return 720; if(ans==5) return 120; if(ans==4) return 24; if(ans==3) return 6; if(ans==2) return 2; if(ans==1) return 1; if(ans==0) return 0;}int kt(string s){ int sum=0; int ans=7; for(int i=0;i<N;i++) { sum+=compress(i,s)*fac(ans); ans--; } return sum;}string Fun(string ss,int n){ int l,r; if(n==0) { l=7; r=0; while(l>r) { swap(ss[l],ss[r]); l--; r++; } return ss; } if(n==2) { swap(ss[6],ss[2]); swap(ss[1],ss[2]); swap(ss[6],ss[5]); return ss; } if(n==1) { for(int i=3;i>0;i--) swap(ss[i],ss[i-1]); for(int i=4;i<7;i++) swap(ss[i],ss[i+1]); //cout<<ss<<endl; return ss; }}void bfs(){ while(!q.empty()) { node hd=q.front(); q.pop(); node t=hd; int num; for(int i=0;i<3;i++) { t=hd; t.step.push_back(i+'A'); //cout<<t.step<<endl; string ss=hd.s; ss=Fun(ss,i); //用i+'A'方案对ss变形 //cout<<ss<<endl; num=kt(ss); if(!a[num].size()&&num!=0) { a[num]=t.step; t.s=ss; q.push(t); } } }}void ys(){ string bb=b; string cc=c; for(int i=0;i<N;i++) { bb[i]=i+'0'+1; for(int j=0;j<N;j++) if(c[j]==b[i]) cc[j]=i+'0'+1; } //cout<<bb<<endl; //cout<<cc<<endl; b=bb; c=cc;}int main(){ //freopen("in.txt","r",stdin); memset(a,NULL,sizeof(a)); start.s="12345678"; int num=kt(start.s); a[num]=start.step; q.push(start); bfs(); while(cin>>b) { getchar(); cin>>c; ys(); //cout<<b<<endl; //cout<<c<<endl; //cout<<kt(c); cout<<a[kt(c)]<<endl; } return 0;}
发现这个代码其实是可以简化的,今天或者明天我将我自己简化后的代码贴上来。
优化后的代码:首先发现子函数fac可以写成一个数组,可以将结构体node改一下。
原来是这样
struct node{ string s; string step;};
改成这样:
struct node{ string s; int step;};
本来是要储存一个两个string类型的字符串,优化成只用储存一个。有优化了一下ys函数,从O(N^2)优化成O(N*2).
#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<queue>using namespace std;const int N=8;struct node{ string s; int step;};string b,c;queue<node> q;node start;string a[50000];int compress(int k,string s){ int sum=0; for(int i=k+1;i<N;i++) { if(s[i]<s[k]) sum++; } return sum;}int fac[]={0,1,2,6,24,120,720,5040};int kt(string s){ int sum=0; int ans=7; for(int i=0;i<N;i++) { sum+=compress(i,s)*fac[ans]; ans--; } return sum;}string Fun(string ss,int n){ int l,r; if(n==0) { l=7; r=0; while(l>r) { swap(ss[l],ss[r]); l--; r++; } return ss; } if(n==2) { swap(ss[6],ss[2]); swap(ss[1],ss[2]); swap(ss[6],ss[5]); return ss; } if(n==1) { for(int i=3;i>0;i--) swap(ss[i],ss[i-1]); for(int i=4;i<7;i++) swap(ss[i],ss[i+1]); return ss; }}void bfs(){ while(!q.empty()) { node hd=q.front(); q.pop(); node t=hd; int num; for(int i=0;i<3;i++) { t=hd; string ss=hd.s; ss=Fun(ss,i); //用i+'A'方案对ss变形 num=kt(ss); if(!a[num].size()&&num!=0) { a[num]=a[t.step]; a[num].push_back(i+'A'); t.step=num; t.s=ss; q.push(t); } } }}void ys(){ char pos[10]; for(int i=0;i<N;i++) pos[b[i]-'0']=i+1; for(int i=0;i<N;i++) c[i]=pos[c[i]-'0'];}int main(){ //freopen("in.txt","r",stdin); memset(a,NULL,sizeof(a)); start.s="12345678"; start.step=0; int num=kt(start.s); a[num]=""; q.push(start); bfs(); while(cin>>b) { getchar(); cin>>c; ys(); cout<<a[kt(c)]<<endl; } return 0;}
很多大神可以将之优化成0MS,要继续加油!
0 0
- HDU 1430 魔板 搜索
- HDU 1430 魔板
- HDU 1430 魔板 (BFS)
- hdu 1430 魔板
- HDU-1430 魔板
- hdu 1430 魔板
- HDU 1430 魔板
- HDU 1430 魔板
- hdu 1430+hdu 3567(预处理)
- hdu 1430 魔板 (预处理+置换+bfs)
- HDU 1430 魔板(BFS+HASH+置换)
- HDU - 1430 魔板 (bfs预处理 + 康托)
- HDU 1430+BFS
- HDU 1430 搜索
- hdu 1430 魔板(bfs+康拓展开)
- hdu 1430 魔板(bfs+预处理+康托展开)
- hdu 1430 魔板(康托展开+BFS+巧妙转换)
- HDU 1430 魔板 [BFS+康拓展开]【数学】
- java中包装类及装箱拆箱
- Hive笔记四:Hive的组件和工作流程
- MySQL备份与恢复
- SQL 基础
- Spring AOP概念
- hdu 1430 魔板
- Spring MVC 解读——@RequestMapping
- 搜索二维矩阵 II
- 关于findviewbyid
- 大话数据结构--排序
- Spring MVC 解读——@RequestMapping
- HLL select from 语言
- 剑指offer—栈的压入、弹出序列
- [深入理解Java虚拟机]第一章实战 自己编译JDK