八数码第二境界——暴力反向BFS+康托展开判重
来源:互联网 发布:车牌照制作软件 编辑:程序博客网 时间:2024/06/06 00:30
(八数码的第一境界必须看了再看本文)
与上文有所区别,上文采用的是string存储状态,这里采用的是char[],可以增加性能。
上文采用的是map判重,这里采用的是康托展开看看是全排列的第几个来判重。
所以本文最大的问题是领悟康托展开。因为这里是1到x占据9个位置,所以就等于是求这9个位置的全排列了,而了解全排列的人会知道,康托展开是做全排列最好的方式。如果不太清楚用康托展开求全排列的同学,可以看http://blog.csdn.net/qq_36523667/article/details/78659214
结构体
- struct node
- {
- char str[10];
- vector<int>res;
- int index,hashnum;
- };
数组通过康托展开求得是全排列的第几个,他这里转化成hash值仅仅是便于比较大小
int fac[] = {1,1,2,6,24,120,720,5040,40320};
- int KT(char ss[])
- {
- int i, j, t, sum;
- int s[10];
- for(i=0;i<9;i++)
- {
- if(ss[i]=='x')
- s[i]=0;
- else
- s[i]=ss[i]-'0';
- }
- sum = 0;
- for (i=0; i<9; i++)
- {
- t = 0;
- for (j=i+1; j<9; j++)
- if (s[j] < s[i])
- t++;
- sum += t*fac[9-i-1];
- }
- return sum+1;
- }
具体的BFS,和上文基本类似
- while(!q.empty())
- {
- g=q.front();q.pop();
- if(KT(g.str)==over)
- {
- res=g.res;
- return true;
- }
- h=g;
- if((h.index+1)%3!=0)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
- h.index++;
- h.res.push_back(4);
- int t=KT(h.str);
- if(!vis[t])
- {
- vis[t]=true;
- q.push(h);
- }
- }
第二个if,是不为最后一列的情况,肯定可以右移
和右边的数交换
x在char中的索引加一位
4入vector,4代表右移操作
最后用康托找到是全排列的第几个,看看有没有访问过,没访问过就置为已访问状态,并且入队列。
全部代码
- #define N 512345
- char ss[10];
- struct node
- {
- char str[10];
- vector<int>res;
- int index,hashnum;
- };
- vector<int>res;
- bool vis[N];
- int fac[] = {1,1,2,6,24,120,720,5040,40320};
- int over;
- int KT(char ss[])
- {
- int i, j, t, sum;
- int s[10];
- for(i=0;i<9;i++)
- {
- if(ss[i]=='x')
- s[i]=0;
- else
- s[i]=ss[i]-'0';
- }
- sum = 0;
- for (i=0; i<9; i++)
- {
- t = 0;
- for (j=i+1; j<9; j++)
- if (s[j] < s[i])
- t++;
- sum += t*fac[9-i-1];
- }
- return sum+1;
- }
- bool bfs(char ss[])
- {
- char c;
- queue<node> q;
- while(!q.empty())q.pop();
- over = KT(ss);
- node g,h;
- for(int i=0;i<8;i++)
- g.str[i]=i+1+'0';
- g.str[8]='x';g.str[9]='\0';
- g.res.clear();g.index=8;
- q.push(g);
- while(!q.empty())
- {
- g=q.front();q.pop();
- if(KT(g.str)==over)
- {
- res=g.res;
- return true;
- }
- h=g;
- if((h.index+1)%3!=0)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;
- h.index++;
- h.res.push_back(4);
- int t=KT(h.str);
- if(!vis[t])
- {
- vis[t]=true;
- q.push(h);
- }
- }
- h=g;
- if(h.index%3!=0)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;
- h.index--;
- h.res.push_back(3);
- int t=KT(h.str);
- if(!vis[t])
- {
- vis[t]=true;
- q.push(h);
- }
- }
- h=g;
- if(h.index<6)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;
- h.index+=3;
- h.res.push_back(2);
- int t=KT(h.str);
- if(!vis[t])
- {
- vis[t]=true;
- q.push(h);
- }
- }
- h=g;
- if(h.index>2)
- {
- c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;
- h.index-=3;
- h.res.push_back(1);
- int t=KT(h.str);
- if(!vis[t])
- {
- vis[t]=true;
- q.push(h);
- }
- }
- }
- return false;
- }
- int main()
- {
- int i,j,k,kk,t,x,y,z;
- while(scanf("%s",ss)!=EOF)
- {
- memset(vis,false,sizeof(vis));
- for(i=1;i<9;i++)
- scanf("%s",ss+i);
- if(bfs(ss))
- for(i=res.size()-1;i>=0;i--)
- {
- if(res[i]==1)printf("d");
- if(res[i]==2)printf("u");
- if(res[i]==3)printf("r");
- if(res[i]==4)printf("l");
- }
- else
- printf("unsolvable");
- printf("\n");
- }
- return 0;
- }
阅读全文
0 0
- 八数码第二境界——暴力反向BFS+康托展开判重
- 八数码第三境界——暴力反向BFS+康托展开判重+打表
- 八数码第四境界——暴力反向BFS+康托展开判重+打表+回溯记录路径
- 八数码第五境界——双向BFS+康托展开判重+回溯记录路径
- 八数码第六境界——双向BFS+康托展开判重+回溯记录路径+逆序数判无解
- 八数码第七境界——A*之曼哈顿+康托展开判重+回溯记录路径+逆序数判无解
- POJ 1077 八数码(康托展开+暴力bfs)
- 八数码第一境界——暴力反向BFS+存状态
- hdoj--1043--八数码--bfs||A*(HASH判重--康托)
- HDU 1043 Eight ((八数码问题)逆向BFS + 康托定理判重)
- 蓝桥杯 历届试题 九宫重排 (八数码问题--康托展开去重 + bfs搜索)
- [POJ]1077 Eight 八数码:康托展开+BFS
- hdu1043Eight (经典的八数码)(康托展开+BFS)
- hdu1043Eight (经典的八数码)(康托展开+BFS)
- 【康托展开+状压BFS】poj1077 Eight(八数码问题)
- POJ 1077 Eight 八数码问题[康托展开 + BFS]
- BFS+康托展开(洛谷1379 八数码难题)
- POJ1077 HDU1043 Eight 八数码第四境界 双向广搜 康托展开 逆康托
- Paper Signals 初探
- 反射设置和获取值
- python 读取并显示图片的两种方法
- JMM浅析
- 解决APP启动会有短暂的白屏出现
- 八数码第二境界——暴力反向BFS+康托展开判重
- springcloud实战之2 服务注册与发现(eureka实现)
- VsVim配置教程
- 学会用好 Visual Studio Code
- Eclipse中Maveng工程,add dependency没有包,解决办法
- jquery练习9 弹出层样式设置(TBC)
- 图像的梯度(The Gradient of Image)
- 真正的个性化Rss 阅读器
- Cmake编译opencv3.1出现project files may be invalid,编译后的opencv3.1的debug附加依赖项在最后