zoukankan      html  css  js  c++  java
  • UESTC_贪吃蛇 CDOJ 709

    相信大家都玩过贪吃蛇游戏吧。

    n×m的迷宫中,有着一条长度不超过9的贪吃蛇,它已经将所有的食物吃光了,现在的目标是移动到出口。

    它走的时候不能碰到自己的身体,也不能碰到墙壁。(如果贪吃蛇的长度>3并且下一步要走到自己的尾部,是合法的)

    问它能不能走到出口,如果能,最少要移动几步?

    Input

    数据包含多组数据,请读入到文件末尾EOF

    每组数据第一行包含两个整数n,m(1n,m15)代表迷宫的大小。

    接下来n行,每行包含一个长度为m的字符串,来表示迷宫。

    字符串中仅包含.#@1 ~ 9.代表空地 # 代表墙 数字一定是1k 连续的k个数字,代表贪吃蛇,1代表它的头,k代表它的尾,数据保证数字i一定和数字i+1在迷宫中相邻。 @ 代表出口。

    Output

    对于每组数据,先输出Case #i: ,i为当前数据组数。

    接下来一个数,代表贪吃蛇最少需要移动的步数,若无法移动出去输出-1

    解题报告

    主要是判重问题

    肯定不能vis[15][15].....x9

    内存依然爆炸,其实大部分都是没有使用的,因此我们考虑到

    蛇的每截身体较于前面一截只有 4 种状态,我们用4进制来压缩蛇的身体,这样就能存下了,注意蛇头可以移动到最后一截身体所在的位置.

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int Max = 15;
    char G[Max+2][Max+2];
    bool vis[15][15][9850];
    int  R,C,targetx,targety,n;
    // n is snake-body num
    int  dir[4][2] ={-1,0,1,0,0,-1,0,1};
    int  caculate[8] ={1,3,9,27,81,243,729,2187};
    typedef struct status
    {
      int x[9];
      int y[9];
      int step;    
    };
    
    
    status ori;
    status thisq[1000000];
    
    
    int getturn(int x,int y,int x0,int y0){
    if (x - x0 == 1) return 0;
    if (x - x0 == -1) return 1;
    if (y - y0 == 1) return 2;
    if (y - y0 == -1) return 3;
    printf("Error at get turn!
    ");        
    }
    
    int getcode(status& x){
    int buffer[12];
    int code = 0;
    for(int i = 1;i<n;++i)
     code += getturn(x.x[i],x.y[i],x.x[i-1],x.y[i-1]) * caculate[i-1];
    return code;
    }
    
    
    bool judge(status& x){
    int tx = x.x[0];
    int ty = x.y[0];
    for(int i = 1;i<n;++i)
     if(x.x[i] == tx && x.y[i] == ty)
      return false;
    return true;    
    }
    
    bool dfs1(int x,int y){
    int front = 0,rear = 0;
    int q[8000][2];
    bool evis[15][15];
    memset(evis,false,sizeof(evis));
    evis[x][y] = true;
    q[rear][0] = x;
    q[rear++][1] = y;
    while(front < rear)
    {
        int tx = q[front][0];
        int ty = q[front++][1];
        if (tx == targetx && ty == targety) return true;
        for(int i = 0;i<4;++i)
         {
             int newx = tx + dir[i][0];
             int newy = ty + dir[i][1];
             if (!evis[newx][newy] && G[newx][newy] != '#' && newx < R && newx >=0 && newy < C && newy >=0)
              {
                  q[rear][0] = newx;
                  q[rear++][1] = newy;
                  evis[newx][newy] = true;
              }
          }
    }
    
    
    
    return false;    
    }    
    
    
    
    int dfs(){
    int front = 0,rear = 0;
    ori.step = 0;
    thisq[rear++] = ori;
    vis[ori.x[0]][ori.y[0]][getcode(ori)] = true;    
    while(front < rear)
    {
     int tx = thisq[front].x[0];
     int ty = thisq[front].y[0];
     int step = thisq[front].step;
     if (tx == targetx && ty == targety) return step;
     for(int i = 0 ;i < 4;++i)
     {
         int newx = tx + dir[i][0];
         int newy = ty + dir[i][1];
         int newstep = step+1;
         if (newx >= R || newx < 0 || newy >=C || newy < 0 || G[newx][newy] == '#') 
          continue;
         status newst;
         newst.x[0] = newx;
         newst.y[0] = newy;
         newst.step = step + 1;
         for(int j=1;j<n;++j)
          {
              newst.x[j] = thisq[front].x[j-1];
              newst.y[j] = thisq[front].y[j-1];
          }
        if (!vis[newst.x[0]][newst.y[0]][getcode(newst)] && judge(newst))
         {
             thisq[rear++] = newst;
             vis[newst.x[0]][newst.y[0]][getcode(newst)] = true;
         }
     }
     
     front++;
    }
    
    return -1;
    }
    
    
    bool input(){
    while(scanf("%d%d%*c",&R,&C)==2)
    {
     n = 0;
     memset(vis,false,sizeof(vis));
     for(int i = 0;i<R;++i)
      gets(&G[i][0]);
     for(int i = 0;i<R;++i)
      for(int j = 0;j<C;++j)
       if(G[i][j] == '@')
       {
           targetx = i;
           targety = j;
       }    
       else if(G[i][j] <= '9' && G[i][j] >= '1')
       {
           ori.x[G[i][j] - '1'] = i;
           ori.y[G[i][j] - '1'] = j;
           n ++ ;
       }
     return true;
    }
    return false;
    }
    
    
    int main(int argc,char * argv[]){
    int T = 1;
    while(input() == true)
    {
     if(!dfs1(ori.x[0],ori.y[0]))
      {
          cout << "Case #"<< T++ <<": -1" <<endl;
          continue;
      }
     int ans = dfs();
     cout << "Case #"<< T++ <<": "<< ans <<endl;
    }
    return 0;    
    }
    No Pain , No Gain.
  • 相关阅读:
    SPA项目开发之动态树以及数据表格和分页
    SPA项目开发之首页导航左侧菜单栏
    SPA项目开发之登录
    使用vue-cli搭建spa项目
    Splay 平衡树
    主席树(可持久化线段树 )
    P3195 [HNOI2008]玩具装箱TOY
    P2962 [USACO09NOV]灯Lights
    【hdu4405】AeroplaneChess
    HDU3853:LOOPS
  • 原文地址:https://www.cnblogs.com/Xiper/p/4455053.html
Copyright © 2011-2022 走看看