九宫重拍(bfs + 康拓展开)
我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
123.46758
46758123.
- #include<iostream>
- #include <cstdio>
- #include <queue>
- #include <cstring>
- using namespace std;
- typedef long long LL;
- struct Node{
- int cur[];
- LL step;
- };
- Node s, e;
- const int N = 1e6;
- const int Next[][] = {{, }, {, }, {-, }, {, -}};//搜索的四个方向
- bool vis[N * ];//标记数组
- int fac[] = {, , , , , , , , , };//前几个数的阶乘
- LL cantor(int s[])//康拓展开
- {
- LL ans = ;
- int n = ;
- for (int i = ; i < n - ; i++)
- {
- int tmp = ;
- for (int j = i + ; j < n; j++)
- if (s[j] < s[i])
- tmp++;
- ans += fac[n - i - ] * tmp;
- }
- return ans;
- }
- void cantor_reverse(int index, int a[])//康拓展开逆, 在本道题中未使用
- {
- index--;
- int n = ;
- bool visit[];
- memset(visit, false, sizeof(visit));
- for (int i = ; i < n; i++)
- {
- int tmp = index / fac[n - i - ];
- for (int j = ; j <= tmp; j++)
- if (visit[j])
- tmp++;
- a[i] = tmp + ;
- visit[tmp] = true;
- index %= fac[n - i - ];
- }
- }
- bool ischecked(int row, int col)//检查是否满足移动的条件
- {
- return (row > && col > && row < && col < );
- }
- bool matched(Node node)//看是否达到给定的状态
- {
- for (int i = ; i < ; i++)
- if (node.cur[i] != e.cur[i])
- return false;
- return true;
- }
- LL bfs()
- {
- memset(vis, false, sizeof(vis));
- queue<Node> Q;
- s.step = ;
- Q.push(s);
- Node p, q;
- int start_num = cantor(s.cur);
- vis[start_num] = true;//标记第一个元素
- while (!Q.empty())
- {
- p = Q.front();
- Q.pop();
- int pos;
- for (pos = ; pos < ; pos++)
- if (p.cur[pos] == )//将"."当成9来计算
- break;
- int row, col, new_row, new_col;
- row = pos / + ;
- col = pos % + ;
- for (int i = ; i < ; i++)
- {
- new_row = row + Next[i][];
- new_col = col + Next[i][];
- if (ischecked(new_row, new_col))//判断是否满足可移动的条件
- {
- q = p;
- q.step = p.step + ;
- //下面三步是交换这两个数(也就是移动到空位去)
- int t = q.cur[(row - ) * + col - ];
- q.cur[(row - ) * + col - ] = q.cur[(new_row - ) * + new_col - ];
- q.cur[(new_row - ) * + new_col - ] = t;
- if (matched(q))//如果找到之后直接返回
- {
- return q.step;
- }
- int num = cantor(q.cur);
- if (!vis[num])
- {
- vis[num] = true;
- Q.push(q);
- }
- }
- }
- }
- return -;//找不到就返回-1
- }
- int main()
- {
- char sta[], en[];
- scanf("%s %s", sta, en);
- for (int i = ; i < ; i++)
- if (sta[i] != '.')
- s.cur[i] = sta[i] - '';
- else
- s.cur[i] = ;//将'.'看成9
- for (int i = ; i < ; i++)
- if (en[i] != '.')
- e.cur[i] = en[i] - '';
- else
- e.cur[i] = ;
- LL tmp = bfs();
- printf("%lld\n", tmp);
- return ;
- }
九宫重拍(bfs + 康拓展开)的更多相关文章
- Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...
- bnuoj 1071 拼图++(BFS+康拓展开)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071 [题意]:经过四个点的顺逆时针旋转,得到最终拼图 [题解]:康拓展开+BFS,注意先预处理,得 ...
- hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)
http://acm.hdu.edu.cn/showproblem.php?pid=1043 http://poj.org/problem?id=1077 Eight Time Limit: 1000 ...
- 8数码,欺我太甚!<bfs+康拓展开>
不多述,直接上代码,至于康拓展开,以前的文章里有 #include<iostream> #include<cstdio> #include<queue> using ...
- hdu-1043 bfs+康拓展开hash
因为是计算还原成一种局面的最短步骤,应该想到从最终局面开始做bfs,把所有能到达的情况遍历一遍,把值存下来. bfs过程中,访问过的局面的记录是此题的关键,9*9的方格在计算过程中直接存储非常占内存. ...
- HDU 4531 bfs/康拓展开
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4531 吉哥系列故事——乾坤大挪移 Time Limit: 2000/1000 MS (Java/Othe ...
- 蓝桥杯 历届试题 九宫重排 (bfs+康托展开去重优化)
Description 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的 ...
- cdoj 414 八数码 (双向bfs+康拓展开,A*)
一道关乎人生完整的问题. DBFS的优越:避免了结点膨胀太多. 假设一个状态结点可以扩展m个子结点,为了简单起见,假设每个结点的扩展都是相互独立的. 分析:起始状态结点数为1,每加深一层,结点数An ...
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...
随机推荐
- uva 1378 A Funny Stone Game (博弈-SG)
题目链接:http://vjudge.net/problem/viewProblem.action?id=41555 把第i堆的每个石子看出一堆个数为n-i的石子,转换为组合游戏 #include & ...
- jQuery图片滑动
一个非常简单实用的jQuery插件 可以用在页面的顶部广告展示 http://slidesjs.com/ 一个需要注意的问题, 就是在手机等客户端(IOS8以上), 使用此插件时, 经常会触发插件的r ...
- Linux 4.1内核编译报告
编译环境 Arch Linux on VirtualBox 下载内核 https://www.kernel.org/ 下载的内核压缩包,此时的最新内核版本为4.1: 解压包 # tar -xvJf l ...
- CentOS 6.5下安装MySql 5.7
不管您按下面的方法安装成功否,请留个言,把您遇到的问题写上共勉! 包下载http://url.cn/WrNg5S 环境: 1).软硬件:E6420双核CPU,8G内存,1T硬盘 2).虚拟机下 Cen ...
- C#.net 货币格式转换
/// <summary> /// 输入Float格式数字,将其转换为货币表达方式 /// </summary> /// <param name="ftype& ...
- 19 Remove Nth Node From End of List(去掉链表中倒数第n个节点Easy)
题目意思:去掉链表中倒数第n个节点 思路:1.两次遍历,没什么技术含量,第一次遍历计算长度,第二次遍历找到倒数第k个,代码不写了 2.一次遍历,两个指针,用指针间的距离去计算. ps:特别注意删掉 ...
- LoadRunner安装停在注册界面安装失败----解决办法之一
今天下了个LoadRunner11.5玩玩,准备测手头上准备发布的项目性能,结果安装的时候,报错“Error Creating system registry entry”,在51testing搜索各 ...
- jQuery delegate方法实现Ajax请求绑定事件不丢失
给元素绑定click事件后 ,遇到一个问题:当执行一些ajax请求,再次调用此页面,里面的这个click事件就失效了 比如说:我的分页是一个ajax请求 但我点下一页时 后生成的元素a就没有了clic ...
- Win7下启用IIS7
1.进入“控制面板-->程序”: 2.点击“打开或关闭Windows功能” 3.选择“Internet信息服务”相关选项,如下: 点击“确定”后,请稍等.. 5.启用成功后,可在浏览器访问:ht ...
- debian小巧好看的桌面
先看完,不然,你一定会后悔的..不好看,你打我.. sudo apt-get install xfce4 sudo apt-get install xfce4-goodies sudo apt-get ...