Today I want to introduce an interesting game to you. Like eight puzzle, it is a square board with 9 positions,
but it filled by 9 numbered
tiles. There is only one type of valid move, which is to rotate one row or column. That is, three tiles in a row or column are moved towards the head by one tile and the head tile is moved to the end of the row or column. So it has 12 different
moves just as the picture left. The objective in the game is to begin with an arbitrary configuration of tiles, and move them so as to get the numbered tiles arranged as the target configuration.

Now the question is to calculate the minimum steps required from the initial configuration to the final configuration. Note that the initial configuration is filled with a permutation of 1 to 9,
but the final configuration is filled with numbers and * (which can be any number).

Input

The first line of input contains an integer T (T≤1000),
which is the number of data sets that follow.

There are 6 lines
in each data set. The first three lines give the initial configuration and the next three lines give the final configuration.

Output

For every test case, you should output Case #k: first, where k indicates
the case number and starts at 1.
Then the fewest steps needed. If he can’t move to the end, just output No Solution! (without quotes).

Sample Input



1 2 3 

4 5 6 

7 8 9 

1 2 3 

4 5 6 

7 9 8 

1 2 3 

4 5 6 

7 8 9 

8 * 9 

5 3 7 

2 * *

Sample Output

Case #1: No Solution!

Case #2: 7

康托展开总结:

http://blog.csdn.net/dacc123/article/details/50952079

利用康托展开

把所有状态bfs一次,

然后再去做

利用康托展开进行bfs预处理。题目给的一个起始的九宫格,和一个目标的九宫格。 不能直接用目标的九宫格去找起始的九宫格,会超时,应该根据把起始九宫格当作 

1 2 3 

4 5 6 

7 8 9 

然后确定目标九宫格是怎么样的,这样就可以直接用之前打的表了。预处理就是处理1 2 3 4 5 6 7 8 9到每种九宫格的步数

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <queue> using namespace std;
struct Node
{
int a[5][5];
int sta;
};
queue<Node> q;
int b[10];
int fac[10];
int vis[400000];
int pre[400000];
int ans;
int f1[10];
int f2[10];
int tran[10];
char ch[10];
bool used[10];
Node cyk;
void facfun()
{
fac[0]=1;
for(int i=1;i<=9;i++)
{
fac[i]=i*fac[i-1];
}
}
int kt(Node q)
{
int cnt=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
b[++cnt]=q.a[i][j];
int sum=0,num=0;
for(int i=1;i<=9;i++)
{
num=0;
for(int j=i+1;j<=9;j++)
{
if(b[i]>b[j])
num++;
}
sum+=num*fac[9-i];
}
return sum;
}
void bfs(Node t)
{
q.push(t);
vis[t.sta]=1;
pre[t.sta]=0;
while(!q.empty())
{
Node term=q.front();
q.pop();
for(int i=1;i<=12;i++)
{ Node temp=term;
if(i<=3)
{
temp.a[i][1]=term.a[i][3];
temp.a[i][2]=term.a[i][1];
temp.a[i][3]=term.a[i][2];
}
else if(i>3&&i<=6)
{
temp.a[i-3][1]=term.a[i-3][2];
temp.a[i-3][2]=term.a[i-3][3];
temp.a[i-3][3]=term.a[i-3][1];
}
else if(i>6&&i<=9)
{
temp.a[1][i-6]=term.a[3][i-6];
temp.a[2][i-6]=term.a[1][i-6];
temp.a[3][i-6]=term.a[2][i-6];
}
else if(i>9&&i<=12)
{
temp.a[1][i-9]=term.a[2][i-9];
temp.a[2][i-9]=term.a[3][i-9];
temp.a[3][i-9]=term.a[1][i-9];
}
int state=kt(temp);
if(vis[state])
continue; temp.sta=state;
vis[state]=1;
pre[state]=pre[term.sta]+1; q.push(temp);
} }
}
void init()
{
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
facfun();
Node st;int cnt=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
st.a[i][j]=++cnt;
st.sta=0;
bfs(st);
}
int anspos;
void dfs(int i)
{
if(i==10)
{
/*for(int p=1;p<=3;p++)
{
for(int k=1;k<=3;k++)
{
cout<<cyk.a[p][k]<<" ";
}
cout<<endl;
}*/
int c=pre[kt(cyk)];
if(c==-1) return;
ans=min(ans,c);return;
}
if(f2[i]==0)
{
for(int j=1;j<=9;j++)
{
if(!used[j])
{
used[j]=true;
int y=i%3,x;
if(y==0){x=i/3;y=3;}
else {x=i/3+1;}
cyk.a[x][y]=j;
dfs(i+1);
used[j]=false;
}
}
}
else
{
int y=i%3,x;
if(y==0){x=i/3;y=3;}
else {x=i/3+1;}
cyk.a[x][y]=f2[i];
dfs(i+1);
} } int main()
{
int t;
scanf("%d",&t);
init();
int cas=0;
while(t--)
{
memset(used,0,sizeof(used));
for(int i=1;i<=9;i++)
{
scanf("%d",&f1[i]);
tran[f1[i]]=i;
}
for(int i=1;i<=9;i++)
{
scanf("%s",ch);
f2[i]=ch[0]-'0';
if(f2[i]>=1&&f2[i]<=9)
f2[i]=tran[f2[i]],used[f2[i]]=true;
else
f2[i]=0;
}
ans=1000000;
dfs(1);
if(ans>=1000000)
printf("Case #%d: No Solution!\n",++cas);
else
printf("Case #%d: %d\n",++cas,ans);
}
return 0;
}

UESTC 485 Game(康托,BFS)的更多相关文章

  1. UESTC 485 Game(康托展开,bfs打表)

    Game Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status t ...

  2. CDOJ 485 UESTC 485 Game (八数码变形,映射,逆cantor展开)

    题意:八数码,但是转移的方式是转动,一共十二种,有多组询问,初态唯一,终态不唯一. 题解:初态唯一,那么可以预处理出012345678的所有转移情况,然后将初态对012345678做一个映射,再枚举一 ...

  3. loj 1165(bfs+康托展开)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26879 思路:题目意思很简单,就是通过一些位置的交换,最后变成有序 ...

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

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

  5. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  6. HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

    http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...

  7. [HDOJ1043]Eight(康托展开 BFS 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 八数码问题,因为固定了位置所以以目标位置开始搜索,把所有情况(相当于一个排列)都记录下来,用康托 ...

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

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

  9. hdu1043Eight (经典的八数码)(康托展开+BFS)

    建议先学会用康托展开:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description The 15-puzzle ...

随机推荐

  1. 使用 原生js 制作插件 (javaScript音乐播放器)

    1.引用页面 index.html <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  2. hibernate 继承映射关系( SINGLE_TABLE)

    三种继承映射关系.   1,SINGLE_TABLE   person student  teacher 在一个表中,student和teacher继承自person,通过一个Discriminato ...

  3. iOS原生推送(APNS)进阶iOS10推送图片、视频、音乐

    代码地址如下:http://www.demodashi.com/demo/13208.html 前言 我们首先要在AppDelegate里面进行iOS的适配,可以参考这篇文章 iOS原生推送(APNS ...

  4. 编写C函数的技术-《lua程序设计》 27章 学习

    1.数组操作 void lua_rawgeti(lua_State * L ,int index,int key) void lua_rewseti(lua_State * L,int index,i ...

  5. Oracle undo 表空间管理 (摘DAVID)

    Oracle 的Undo有两种方式: 一是使用undo 表空间,二是使用回滚段. 我们通过 undo_management 参数来控制使用哪种方式,如果设为auto,就使用UNDO 表空间,这时必须要 ...

  6. 异步编程C#回调方法

    1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某个操作时,应用程序可在异步方 ...

  7. DSP6455的cmd文件

    DSP6455的cmd文件 CMD 的专业名称叫链接器配置文件,存放链接器的配置信息,DSP编译器的编译结果是未定位的,DSP也没有操作系统来定位执行代码,DSP系统的配置需求也不尽相同,因此需要定义 ...

  8. Android开发系列之性能优化

    一直想整理一篇关于Android性能优化的博客,正好今天借鉴一些书籍资料,总结一下自己对于这块的一些认识.相信大家都听说过16ms的原则,即每两个画面之间的绘制时间间隔不能超过16ms,否则人眼能够感 ...

  9. LNMP平滑升级nginx并安装ngx_lua模块教程

    #ngx_lua module项目地址 https://github.com/chaoslawful/lua-nginx-module 在LNMP安装包后,重编译nginx,并添加ngx_lua模块 ...

  10. python3 读取csv的常用语法

    import csv #打开文件,用with打开可以不用去特意关闭file了,python3不支持file()打开文件,只能用open() with open("info.csv" ...