zoukankan      html  css  js  c++  java
  • UESTC_棋盘游戏 CDOJ 578

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

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

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

    Input

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

    对于每一组数据,第一行是两个整数N,M,其中2N61M4

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

    保证数据是合法的。

    Output

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

    Sample input and output

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

    解题报告

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

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

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <queue>
      7 
      8 
      9 using namespace std;
     10 
     11 const int Max= 6;
     12 int N,M,tid,ttx,tty;
     13 char G[Max][Max];
     14 bool vis[36][36][36][36];
     15 
     16 typedef struct status{
     17 int pos[4],step,pol,f;    
     18 friend bool operator < (status a,status b)
     19 {
     20   if (a.step + a.f < b.step + b.f) return false;
     21   if (a.step + a.f > b.step + b.f) return true;
     22   if (a.step < b.step) return false;
     23   else 
     24   return true;
     25 }
     26 };
     27 
     28 priority_queue<status>q;
     29 status start;
     30 int pol;
     31 int dir[4][2] = {0,1,0,-1,1,0,-1,0};
     32 
     33 /*A* */
     34 int caculatef(status& x){
     35 int result = 0;
     36 for(int i = 0;i<M;++i)
     37  result += (abs(x.pos[i] / N - ttx) + abs(x.pos[i] % N - tty) );
     38 return result;
     39 }
     40 
     41 
     42 bool judge(status &x){
     43 for(int i = x.pol;i < M;++i)
     44  for(int j = i;j < M;++j)
     45   if (i != j)
     46    {  
     47       int tx1 = x.pos[i] / N;
     48       int ty1 = x.pos[i] % N;
     49       int tx2 = x.pos[j] / N;
     50       int ty2 = x.pos[j] % N;
     51       if (tx1 == tx2 && abs(ty1 - ty2) == 1) return false;
     52       else if(ty1 == ty2 && abs(tx1-tx2) == 1) return false;
     53       else if(tx1 == tx2 && ty1 == ty2) return false;
     54    }
     55 return true;
     56 }
     57 
     58 
     59 int bfs(){
     60 memset(vis,false,sizeof(vis));
     61 vis[start.pos[0]][start.pos[1]][start.pos[2]][start.pos[3]] = true;
     62 start.step = 0;
     63 q.push(start);
     64 while(!q.empty())
     65 {
     66   status temp = q.top();q.pop();       
     67   if(temp.pos[temp.pol] == tid)
     68        temp.pol++;           
     69   if (temp.pol == M) return temp.step;
     70   for(int i = temp.pol;i<M;++i)
     71        for(int j = 0;j<4;++j)
     72          {
     73              int newx = temp.pos[i] / N + dir[j][0];
     74              int newy = temp.pos[i] % N + dir[j][1];
     75              if (newx >= N || newx < 0 || newy >= N || newy < 0) continue;
     76         int nid =  newx * N + newy;
     77         status nst = temp;
     78         nst.pos[i] = nid;
     79         if (!judge(nst)) continue;
     80         if (vis[nst.pos[0]][nst.pos[1]][nst.pos[2]][nst.pos[3]] ) continue;
     81         vis[nst.pos[0]][nst.pos[1]][nst.pos[2]][nst.pos[3]] = true;
     82         nst.step = temp.step + 1;
     83         nst.f = caculatef(nst);
     84         q.push(nst);
     85         }
     86 }
     87 
     88 return -1;
     89 }
     90 
     91 
     92 int main(int argc,char * argv[]){
     93 int T;
     94 scanf("%d",&T);
     95 while(T--)
     96 {
     97   while(!q.empty())
     98    q.pop();
     99   for(int i = 0;i<4;++i)
    100    start.pos[i] = 0;
    101   start.pol = 0;
    102   scanf("%d%d%*c",&N,&M);
    103   for(int i = 0;i<N;++i)    
    104    gets(G[i]);
    105   for(int i = 0;i<N;++i)
    106    for(int j = 0;j<N;++j)
    107     if(G[i][j] <= '4' && G[i][j] >='1')
    108      start.pos[G[i][j] - '1'] = i*N+j;
    109     else if(G[i][j] == 'x')
    110      tid = i*N + j;
    111   ttx = tid / N;
    112   tty = tid % N;
    113   start.f = caculatef(start);
    114   cout << bfs() << endl;
    115 }
    116 return 0;    
    117 }
    No Pain , No Gain.
  • 相关阅读:
    三元表达式、列表推导式、生成器表达式、递归、匿名函数
    nonlocal关键字、装饰器
    函数嵌套、作用域、闭包
    实参和形参
    函数基础
    文件操作
    字符编码
    推荐一个纯JavaScript编写的图表库——Highcharts
    推荐web 前端代码的编辑分享平台——RunJS
    了解腾讯
  • 原文地址:https://www.cnblogs.com/Xiper/p/4467808.html
Copyright © 2011-2022 走看看