最近昀昀学习到了一种新的棋盘游戏,这是一个在一个N×N的格子棋盘上去搞M个棋子的游戏,游戏的规则有下列几条:

  1. 棋盘上有且仅有一个出口
  2. 开始时没有哪个棋子在出口,而且所有棋子都不相邻(这里的相邻是指上下左右四个方向)
  3. M个棋子分别记为1到M
  4. 每个时刻你可以移动一个棋子向它相邻的四个格子移动一步
  5. 你需要保证任意时刻棋盘上所有棋子都不相邻
  6. 只有当前棋盘上编号最小的棋子移动到出口时才能取走改棋子。
  7. 所有棋子都移走的时候游戏结束

对于一个给定的游戏局面,昀昀最少要多少步才能结束这个游戏呢?

Input

第一行有一个整数T,(T≤200),表示测试数据的组数。

对于每一组数据,第一行是两个整数N,M,其中2≤N≤6, 1≤M≤4。

接下来是一个N×N的棋盘,其中o代表空格子,x代表出口,其余的1到M代表这M个棋子。

保证数据是合法的。

Output

对于每一组数据输出最少步数,如果无解输出−1。

Sample input and output

Sample Input Sample Output
2
3 2
x2o
ooo
oo1 3 3
xo1
o2o
3oo
7
-1

解题报告

自己也是太年轻。。以为是道大水题,直接上bfs爆搜,果断TLE。。

略思考后显然是A*算法(大水题。。。曼哈顿距离呐)

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue> using namespace std; const int Max= ;
int N,M,tid,ttx,tty;
char G[Max][Max];
bool vis[][][][]; typedef struct status{
int pos[],step,pol,f;
friend bool operator < (status a,status b)
{
if (a.step + a.f < b.step + b.f) return false;
if (a.step + a.f > b.step + b.f) return true;
if (a.step < b.step) return false;
else
return true;
}
}; priority_queue<status>q;
status start;
int pol;
int dir[][] = {,,,-,,,-,}; /*A* */
int caculatef(status& x){
int result = ;
for(int i = ;i<M;++i)
result += (abs(x.pos[i] / N - ttx) + abs(x.pos[i] % N - tty) );
return result;
} bool judge(status &x){
for(int i = x.pol;i < M;++i)
for(int j = i;j < M;++j)
if (i != j)
{
int tx1 = x.pos[i] / N;
int ty1 = x.pos[i] % N;
int tx2 = x.pos[j] / N;
int ty2 = x.pos[j] % N;
if (tx1 == tx2 && abs(ty1 - ty2) == ) return false;
else if(ty1 == ty2 && abs(tx1-tx2) == ) return false;
else if(tx1 == tx2 && ty1 == ty2) return false;
}
return true;
} int bfs(){
memset(vis,false,sizeof(vis));
vis[start.pos[]][start.pos[]][start.pos[]][start.pos[]] = true;
start.step = ;
q.push(start);
while(!q.empty())
{
status temp = q.top();q.pop();
if(temp.pos[temp.pol] == tid)
temp.pol++;
if (temp.pol == M) return temp.step;
for(int i = temp.pol;i<M;++i)
for(int j = ;j<;++j)
{
int newx = temp.pos[i] / N + dir[j][];
int newy = temp.pos[i] % N + dir[j][];
if (newx >= N || newx < || newy >= N || newy < ) continue;
int nid = newx * N + newy;
status nst = temp;
nst.pos[i] = nid;
if (!judge(nst)) continue;
if (vis[nst.pos[]][nst.pos[]][nst.pos[]][nst.pos[]] ) continue;
vis[nst.pos[]][nst.pos[]][nst.pos[]][nst.pos[]] = true;
nst.step = temp.step + ;
nst.f = caculatef(nst);
q.push(nst);
}
} return -;
} int main(int argc,char * argv[]){
int T;
scanf("%d",&T);
while(T--)
{
while(!q.empty())
q.pop();
for(int i = ;i<;++i)
start.pos[i] = ;
start.pol = ;
scanf("%d%d%*c",&N,&M);
for(int i = ;i<N;++i)
gets(G[i]);
for(int i = ;i<N;++i)
for(int j = ;j<N;++j)
if(G[i][j] <= '' && G[i][j] >='')
start.pos[G[i][j] - ''] = i*N+j;
else if(G[i][j] == 'x')
tid = i*N + j;
ttx = tid / N;
tty = tid % N;
start.f = caculatef(start);
cout << bfs() << endl;
}
return ;
}

UESTC_棋盘游戏 CDOJ 578的更多相关文章

  1. UESTC_握手 CDOJ 913

    握手 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status ...

  2. UESTC_冰雪奇缘 CDOJ 843

    艾莎女王又开始用冰雪魔法盖宫殿了. 她决定先造一堵墙,于是释放魔法让形为直角梯形的冰砖从天而降,定入冻土之中. 现在你将回答女王的询问:某段冻土上冰砖的面积. 注:多块冰砖之间会互相重叠,重叠部分要多 ...

  3. UESTC_敢说就敢做 CDOJ 631

    敢说就敢做 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  4. UESTC_方老师的分身 II CDOJ 915

    方老师的分身 II Time Limit: 10000/5000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  5. UESTC_方老师分身 I CDOJ 914

    方老师分身 I Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit S ...

  6. UESTC_神秘绑架案 CDOJ 881

    神秘绑架案 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  7. UESTC_方老师买表 CDOJ 885

    老师买表 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Stat ...

  8. UESTC_冬马党 CDOJ 882

    冬马党 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Statu ...

  9. UESTC_魔法少女小蟹 CDOJ 710

    小蟹是一名魔法少女,能熟练的施放很多魔法. 有一天魔法学院上课的时候出现了这样一道题,给一个6位数,让大家用自己的魔法,把这个6位数变成另一个给定的6位数. 小蟹翻了下魔法书,发现她有以下6种魔法: ...

随机推荐

  1. wikioi1369 xth 砍树

    题目描述 Description 在一个凉爽的夏夜,xth 和 rabbit 来到花园里砍树.为啥米要砍树呢?是这样滴, 小菜儿的儿子窄森要出生了.Xth这个做伯伯的自然要做点什么.于是他决定带着 r ...

  2. HTML5 CSS3 诱人的实例 :模仿优酷视频截图功能

    一般的视频网站对于用户上传的视频,在用户上传完成后,可以对播放的视频进行截图,然后作为视频的展示图.项目中也可以引入这样的功能给用户一种不错的体验,而不是让用户额外上传一张展示图. 效果图: 看起来还 ...

  3. 【剑指offer】面试题29:数组中出现次数超过一半的数字

    题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  4. 腾讯课堂-草图大师 Sketchup 初级到精通视频讲座

    腾讯课堂-草图大师 Sketchup 初级到精通视频讲座 草图大师 Sketchup 初级到精通视频讲座

  5. Ajax长连接

    所谓的长连接,就是不断去发送请求,把请求阻塞在服务器端,每次超过请求时间就去重新发送请求,保持连接,随时获取服务器端的响应的数据 项目案例: function connection(){       ...

  6. C# 使用枚举获取对应的数组值时

    using System; enum Move { walk, run } class Program { static float[] speedAry = { 50.0f, 200.0f }; p ...

  7. SqlDependency不起作用

    今天使用SqlDependency,结果不起作用,失效,不管数据库怎么修改,这边都没反应,OnChange事件总是不执行,很奇怪.我打开msdn里的例子,代码复制出来,结果没问题,能执行,那剩下来的问 ...

  8. 虚拟机设备直通的两种方式(Working in Progress)

    声明: 本博客欢迎转发.但请保留原作者信息! 博客地址:http://blog.csdn.net/halcyonbaby 内容系本人学习.研究和总结,如有雷同,实属荣幸! pci passthroug ...

  9. EffectiveC#18--用IComparable和IComparer实现对象的顺序关系

    1..Net框架提供了接口来描述对象的顺序关系:IComparable 和IComparer. 2.IComparable 为类定义了自然顺序,实现IComparer接口的类可以描述其它可选的顺序 3 ...

  10. sql service重置自动增长字段数字的方法

    1.--SQL表重置自增长字段(不删除表的数据) DBCC CHECKIDENT('表名', RESEED, 起始数) 2.--删除表数据的同时,重置自动增长字段 truncate table 表名