刚开始不知道有康托展开,一筹莫展,查了一下大神题解。看到说要用康托展开,遂跑去学。
康托展开: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,要继续加油!

hdu 1430 魔板相关推荐

  1. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  2. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  3. hdu 1430+hdu 3567(预处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路:由于只是8种颜色,所以标号就无所谓了,对起始状态重新修改标号为 12345678,对目标状 ...

  4. java51游戏_Java作业实践(一)魔板游戏

    课题:魔板游戏 一.课设要求 1.基本功能 (1)游戏规则 一个3×3的魔板,有一个格子是空的,其他格子内随机放置1-8共8个编号的方块,通过单击任意一个与空格子相邻的方块可以把该方块移入空格子,不断 ...

  5. P2730 魔板 Magic Squares

    不看题解肯定不会系列... 这道题可以用Cantor展开解决. Cantor展开可以求出一个数组是在全排列中的第几个. 具体怎么操作自己百度. Cantor展开的公式是:\(a[1] * (n - 1 ...

  6. 【题解】Luogu P2730 魔板

    蒟蒻的第一道蓝题--好像也没有蓝的程度 一篇无STL的超弱题解(入门写法无误了QAQ 传送门 很经典的一道BFS 这是初始状态. 操作A 操作B 操作C 思路1 不使用cantor展开的情况 1. 对 ...

  7. 洛谷P2730 [IOI]魔板 Magic Squares

    题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜 ...

  8. Magic Squares 魔板 (BFS+HASH)

    Description 在成功地发明了魔方之后,拉比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8 ...

  9. 魔板(洛谷-P2730)

    题目描述 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个 ...

最新文章

  1. Python3中闭包介绍
  2. 阿里面试: 说说强引用、软引用、弱引用、虚引用吧
  3. python各种类型日期转换大全
  4. BZOJ2208 [Jsoi2010]连通数
  5. OpenCV黑白图像增强——灰度级切片
  6. Android 访问本地 HTML
  7. 十分钟搞懂什么是CGI
  8. Android 反编译apk文件(转)
  9. Git-分布式版本控制系统
  10. Could not create a sandbox extension for /
  11. VS2005的几款代码皮肤。
  12. large_margin
  13. 结构之法算法之道CSDN博客-第一期全部博文集锦[CHM 文件下载]
  14. linux磁盘空间用满的处理方法
  15. linux常用命令技巧
  16. 二十四节气-秋分 | 文案、海报
  17. 安卓原生系统开发与逆向工程
  18. node.js毕业设计安卓校园代办助手app(程序+APP+LW)
  19. 转载-Android 前沿UI
  20. 大型C++网络游戏开发视频教程

热门文章

  1. Kamiya丨Kamiya艾美捷抗BCMA单抗,克隆Vicky-2说明书
  2. echarts-legend-自定义图例的图标,未激活图例置灰
  3. 昨晚,我用python帮隔壁小姐姐P证件照 自拍,然后发现。。。
  4. 金融无疆界 风险无极限——中国金融的未来之路
  5. 为什么上传的格式是mp4在网页上无法播放是什么原因呢?
  6. Android 实现答题器功能(通过手势实现翻页效果)...
  7. 一个数如果恰好等于它的因子之和,这个数就称为 “完数 “
  8. 学机器人编程课以后有用吗
  9. UE4 蓝图设置怪物自动寻路
  10. 面试题【jdk8新特性】