UESTC_棋盘游戏 CDOJ 578
最近昀昀学习到了一种新的棋盘游戏,这是一个在一个N×N的格子棋盘上去搞M个棋子的游戏,游戏的规则有下列几条:
- 棋盘上有且仅有一个出口
- 开始时没有哪个棋子在出口,而且所有棋子都不相邻(这里的相邻是指上下左右四个方向)
- M个棋子分别记为1到M
- 每个时刻你可以移动一个棋子向它相邻的四个格子移动一步
- 你需要保证任意时刻棋盘上所有棋子都不相邻
- 只有当前棋盘上编号最小的棋子移动到出口时才能取走改棋子。
- 所有棋子都移走的时候游戏结束
对于一个给定的游戏局面,昀昀最少要多少步才能结束这个游戏呢?
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 |
---|---|
|
|
解题报告
自己也是太年轻。。以为是道大水题,直接上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的更多相关文章
- UESTC_握手 CDOJ 913
握手 Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Status ...
- UESTC_冰雪奇缘 CDOJ 843
艾莎女王又开始用冰雪魔法盖宫殿了. 她决定先造一堵墙,于是释放魔法让形为直角梯形的冰砖从天而降,定入冻土之中. 现在你将回答女王的询问:某段冻土上冰砖的面积. 注:多块冰砖之间会互相重叠,重叠部分要多 ...
- UESTC_敢说就敢做 CDOJ 631
敢说就敢做 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- UESTC_方老师的分身 II CDOJ 915
方老师的分身 II Time Limit: 10000/5000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- UESTC_方老师分身 I CDOJ 914
方老师分身 I Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit S ...
- UESTC_神秘绑架案 CDOJ 881
神秘绑架案 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- UESTC_方老师买表 CDOJ 885
老师买表 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Stat ...
- UESTC_冬马党 CDOJ 882
冬马党 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Statu ...
- UESTC_魔法少女小蟹 CDOJ 710
小蟹是一名魔法少女,能熟练的施放很多魔法. 有一天魔法学院上课的时候出现了这样一道题,给一个6位数,让大家用自己的魔法,把这个6位数变成另一个给定的6位数. 小蟹翻了下魔法书,发现她有以下6种魔法: ...
随机推荐
- 理解mcelog如何工作
前言 本文,带你了解几个问题? 本文重点,主要看案例2,带你很好的理解mcelog如何工作的? mcelog的干什么的? mcelog 是 x86 的 Linux 系统上用来 检查硬件错误,特别是内存 ...
- 第11讲- Android中进程及其优先级
第11讲Android中进程及其优先级 进程与线程: 进程:操作系统结构的基础,资源分配的最小单元,一个操作系统包括多个进程: 线程:线程存在于进程当中,是操作系统调试执行的最小单元,一个进程包括多个 ...
- hdu 5640 King's Cake(模拟)
Problem Description It is the king's birthday before the military parade . The ministers prepared ...
- python之路-模块 splinter
Splinter介绍 Splinter is an open source tool for testing web applications using Python. It lets you au ...
- 海量路由表能够使用HASH表存储吗-HASH查找和TRIE树查找
千万别! 非常多人这样说,也包括我. Linux内核早就把HASH路由表去掉了.如今就仅仅剩下TRIE了,只是我还是希望就这两种数据结构展开一些形而上的讨论. 1.hash和trie/radix ha ...
- CREATE PROCEDURE
1 CREATE PROCEDURE(创建) CREATE PROCEDURE存储过程名(參数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的參数列必须总是存在.假设没有參数,也该使 ...
- css_day5
- html5 音频
目前,web页面上没有标准的方式来播放音频文件,大多数的音频文件是使用插件来播放,而众多的浏览器使用了不同的插件.而html5的到来,给我们提供了一个标准的方式来播放web中音频文件,用户不再为浏览器 ...
- shell参数
shell获取当前执行脚本的路径 filepath=$(cd "$(dirname "$0")"; pwd) 脚本文件的绝对路径存在了环境变量filepath中 ...
- 1203.3——循环语句 之 while
while循环 while循环的一般形式为: while(表达式){ 语句块 }其中表达式称为循环条件,语句块称为循环体. while语句的意思是:先计算表达式的值,当值为真 ...