最近昀昀学习到了一种新的棋盘游戏,这是一个在一个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. JS代码的window.location属性详解

    转载:http://www.5icool.org/a/201105/a564.html 如果你稍微懂一些JS代码,一般都会知道 window.location.href 这个属性.并且用该属性获取页面 ...

  2. PS抠图神器: KnockOut 2.0安装汉化和使用教程

    PS抠图神器: KnockOut 2.0安装汉化和使用教程 http://jingyan.baidu.com/article/6b97984d8aeadc1ca2b0bf3b.html

  3. UVa 1449 - Dominating Patterns (AC自动机)

    题目大意:给出多个字符串模板,并给出一个文本串,求在文本串中出现最多的模板,输出最多的次数并输出该模板(若有多个满足,则按输入顺序输出). 思路:赤裸裸的 AC自动机,上模板. 代码: #includ ...

  4. pyqt字符串分离开,放入列表中

    string1 = ''''' the stirng Has many line In THE fIle ''' list_of_string = string1.split() print list ...

  5. sqlserver练习

    1.基本表的练习: create table Test( name ), age int, sex ) ) alter table Test ) alter table Test ) alter ta ...

  6. Android应用程序启动过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6689748 前文简要介绍了Android应用程 ...

  7. 2016-XCTF Final-Richman

    抽时间将XCTF Final中Richman这个题总结了下.题目及ida idb所在的链接在:http://files.cnblogs.com/files/wangaohui/richman-blog ...

  8. linux下查看文件及目录个数

    linux下查看文件及目录个数1.查看当前文件和目录总数(不包括子目录):ls -l | wc -l 2.查看当前目录下文件个数(不包括子目录):ls -l |grep "^-"| ...

  9. 如何利用 Bootstrap 进行快速 Web 开发

    原文出处: IBM developerworks 了解如何使用 Bootstrap 快速开发网站和 Web 应用程序(包括移动友好型应用程序).Bootstrap 以 LESS 项目为基础,由 Twi ...

  10. 不用position,让div垂直居中

    先弄懂after伪类的用法,就可以很容易理解了. <!DOCTYPE html> <html lang="en"><head> <meta ...