题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26879

思路:题目意思很简单,就是通过一些位置的交换,最后变成有序数列,对于一组序列,我们可以用康托展开然后hash判重。

然后就是普通的bfs,稍微留意一下细节即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int is_prime[]={,,,,,,,,,,,,,,,,,};
int fac[]={,,,,,,,,}; struct Point{
int num,flag;
}; struct Node{
Point state[];
int step;
}st; bool mark[]; int Get_Hash(Node &node)
{
int a[],val=,cnt;
for(int i=;i<;i++)a[i]=abs(node.state[i].num);
for(int i=;i<;i++){
cnt=;
for(int j=;j<i;j++){
if(a[j]>a[i])cnt++;
}
val+=cnt*fac[i];
}
return val;
} bool Judge(Node &node)
{
for(int i=;i<;i++){
if(abs(node.state[i].num)>abs(node.state[i+].num))
return false;
}
return true;
} Node Get_Node(Node &p,int pos1,int pos2,int dir)
{
//pos1->pos2 left
if(dir==){
if(pos1<pos2){
int tmp=p.state[pos1].num,flag=p.state[pos1].flag;
for(int i=pos1;i<=pos2-;i++){
p.state[i].num=p.state[i+].num;
p.state[i].flag=p.state[i+].flag;
}
p.state[pos2-].num=tmp;
p.state[pos2-].flag=flag;
}else {
int tmp=p.state[pos1].num,flag=p.state[pos1].flag;
for(int i=pos1;i>pos2;i--){
p.state[i].num=p.state[i-].num;
p.state[i].flag=p.state[i-].flag;
}
p.state[pos2].num=tmp,p.state[pos2].flag=flag;
}
}else if(dir==){ //pos1->pos2 right
if(pos1<pos2){
int tmp=p.state[pos1].num,flag=p.state[pos1].flag;
for(int i=pos1;i<=pos2-;i++){
p.state[i].num=p.state[i+].num;
p.state[i].flag=p.state[i+].flag;
}
p.state[pos2].num=tmp,p.state[pos2].flag=flag;
}else {
int tmp=p.state[pos1].num,flag=p.state[pos1].flag;
for(int i=pos1;i>=pos2+;i--){
p.state[i].num=p.state[i-].num;
p.state[i].flag=p.state[i-].flag;
}
p.state[pos2+].num=tmp,p.state[pos2+].flag=flag;
}
}
return p;
} void bfs()
{
memset(mark,false,sizeof(mark));
queue<Node>que;
que.push(st);
mark[Get_Hash(st)]=true;
while(!que.empty()){
Node q,pp,p=que.front();
que.pop();
if(Judge(p)){
printf("%d\n",p.step);
return ;
}
for(int i=;i<;i++){
for(int j=;j<;j++)if(i!=j){
if(p.state[i].flag!=p.state[j].flag&&is_prime[abs(p.state[i].num)+abs(p.state[j].num)]){
for(int k=;k<;k++){
pp=p;
q=Get_Node(pp,i,j,k);
int val=Get_Hash(q);
q.step=p.step+;
if(!mark[val]){
mark[val]=true;
que.push(q);
}
}
}
}
}
}
puts("-1");
} int main()
{
int _case,t=;
scanf("%d",&_case);
while(_case--){
for(int i=;i<;i++){
scanf("%d",&st.state[i].num);
st.state[i].flag=(st.state[i].num>?:-);
}
st.step=;
printf("Case %d: ",t++);
bfs();
}
return ;
}

loj 1165(bfs+康托展开)的更多相关文章

  1. HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】

    一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...

  2. hdu1430魔板(BFS+康托展开)

    做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...

  3. Aizu0121 Seven Puzzle(bfs+康托展开)

    https://vjudge.net/problem/Aizu-0121 比八数码要水的多,bfs. 但是做的时候我把康托展开记错了,wa了好几次. 附上康托展开博客详解:https://blog.c ...

  4. 蓝桥杯 历届试题 九宫重排 (bfs+康托展开去重优化)

    Description 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的 ...

  5. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  6. hdu 1430(BFS+康托展开+映射+输出路径)

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

  7. HDU_1430 魔板 【BFS+康托展开+置换】

    一.题面 POJ1430 二.分析 该题与之前做的八数码不同,它是一个2*4的棋盘,并且没有空的区域.这样考虑的情况是很少的,依然结合康托展开,这时康托展开最多也只乘7的阶乘,完全可以BFS先预处理一 ...

  8. HDU - 1430 魔板 【BFS + 康托展开 + 哈希】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...

  9. hdu 5012 bfs 康托展开

    Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submi ...

随机推荐

  1. mysql cluster (mysql 集群)安装配置方案(转)

    一.准备 1.准备服务器 计划建立有5个节点的MySQL CLuster体系,需要用到5台服务器,但是我们做实验时没有这么多机器,可以只用2台,我就是一台本机,一台虚拟机搭建了有5个节点的MySQL ...

  2. myBatis 实现用户表增删查改操作<方法1 没有使用接口的>(最终版)

    在UserMapper.xml中添加增删改查 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...

  3. 在命令行中运行eclipse中创建的java项目

    在命令行中运行eclipse中创建的java项目 博客分类: java相关 javaeclipse命令行  由于项目要求,需要对eclipse中的项目进行打包,似的可以在客户机上不装eclipse的情 ...

  4. motto6

    当你发现自己不错的时候,要适当的给自己加点凉水,让自己知道自己离“不错”还很远.

  5. 繁华模拟赛 David与阶乘

    #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #i ...

  6. 安卓(Android)手机如何安装APK?

    我大天朝的安卓手机只能在一个被阉割的APP市场里玩耍,有些APP可能需要直接安装APK文件.APK 是 Android Package (安卓安装包)安卓手机如何安装APK呢? 在电脑上下载安装APK ...

  7. 怎样从命令行进入mac桌面

    www.iwangzheng.com 刚买的mac电脑,想在终端进入桌面,可以用下面的方式 点击桌面右上方的放大镜搜索到Terminal并打开,输入 $ cd /Users 这里会显示多个用户,进入自 ...

  8. HDU1198水管并查集Farm Irrigation

    Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot ...

  9. Kali Linux下破解WIFI密码挂载usb无线网卡的方法

    Kali Linux下破解WIFI密码挂载usb无线网卡的方法 时间:2014-10-12    来源:服务器之家    投稿:root 首先我要说的是,wifi密码的破解不是想象中的那么容易,目前还 ...

  10. Java单链表、双端链表、有序链表实现

    单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) 有了这两个方法,就可以用单链表来实现一个栈了,见htt ...