• uestc 贪吃蛇


    转自:http://m.blog.csdn.net/blog/u013776011/25992865

    贪吃蛇,首要问题是如何记录蛇的状态,蛇头,蛇身中每个点与上一点之间的方向关系。
    故可以用哈希来定义状态,这里学习了别人的hash方法。每次找到当前点与前面一点的方向关系来确定hash返回值
    剩下的就是直接BFS,每次更新新蛇一定要注意蛇的长度是多少,如果蛇的长度大于等于3,那么碰到蛇的尾部是合法的
    如果蛇的长度小于3,那么碰到蛇尾是不合法的
    另外注意移动过程中那种情况下都不能碰到蛇身
    利用蛇前后位置的一一替换的对应关系,移动蛇身。根据hash判重就可以
    每组数据后要清空队列

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <queue>
      7 #define Mod 1000000007
      8 #define ll long long
      9 using namespace std;
     10 #define N 107
     11 
     12 struct Point
     13 {
     14     int x,y;
     15 }p[11];
     16 
     17 struct node
     18 {
     19     int x,y;
     20     int num,step;
     21 }S;
     22 
     23 char mp[17][17];
     24 int vis[70000][16][16];
     25 int R,C,K;
     26 int EX,EY;
     27 int dx[4] = {1,0,0,-1};
     28 int dy[4] = {0,1,-1,0};
     29 
     30 int p_to_num(Point *p)
     31 {
     32     int i,k;
     33     int res = 0,now = 0;
     34     for(i=1;i<K;i++)
     35     {
     36         int sx = p[i].x;
     37         int sy = p[i].y;
     38         int tx = p[i+1].x;
     39         int ty = p[i+1].y;
     40         if(sx > tx && sy == ty)
     41             k = 3;   //
     42         else if(sx == tx && sy > ty)
     43             k = 2;   //
     44         else if(sx < tx && sy == ty)
     45             k = 0;   //
     46         else if(sx == tx && sy < ty)
     47             k = 1;   //
     48         k <<= now;
     49         now += 2;
     50         res |= k;
     51     }
     52     return res;
     53 }
     54 
     55 bool OK(int nx,int ny)
     56 {
     57     if(nx >= 0 && nx < R && ny >= 0 && ny < C)
     58         return true;
     59     return false;
     60 }
     61 
     62 bool check(int num)
     63 {
     64     int i,j,k;
     65     k = K-1;
     66     int x = 0,y = 0;
     67     while(k--)
     68     {
     69         x += dx[num&3];
     70         y += dy[num&3];
     71         if(x == 0 && y == 0)
     72             return false;
     73         num >>= 2;
     74     }
     75     return true;
     76 }
     77 
     78 int BFS(node S)
     79 {
     80     int i,j,k;
     81     queue<node> que;
     82     memset(vis,0,sizeof(vis));
     83     que.push(S);
     84     vis[S.num][S.x][S.y] = 1;
     85     int MOD = (1<<((K-1)*2));
     86     while(!que.empty())
     87     {
     88         node tmp = que.front();
     89         que.pop();
     90         if(tmp.x == EX && tmp.y == EY)
     91             return tmp.step;
     92         for(i=0;i<4;i++)
     93         {
     94             if(K <= 1 || ((tmp.num&3) != i))
     95             {
     96                 int nx = tmp.x + dx[i];
     97                 int ny = tmp.y + dy[i];
     98                 if(!OK(nx,ny) || mp[nx][ny] == '#')
     99                     continue;
    100                 node now;
    101                 now.num = (tmp.num << 2);
    102                 now.num |= (3-i);
    103                 now.num %= MOD;
    104                 if(vis[now.num][nx][ny])   //状态已走过
    105                     continue;
    106                 if(!check(now.num))    //咬到蛇身
    107                     continue;
    108                 vis[now.num][nx][ny] = 1;
    109                 now.x = nx;
    110                 now.y = ny;
    111                 now.step = tmp.step + 1;
    112                 que.push(now);
    113             }
    114         }
    115     }
    116     return -1;
    117 }
    118 
    119 int main()
    120 {
    121     int i,j,k,cs = 1;
    122     while(scanf("%d%d",&R,&C)!=EOF)
    123     {
    124         K = 1;
    125         for(i=0;i<R;i++)
    126         {
    127             scanf("%s",mp[i]);
    128             for(j=0;j<C;j++)
    129             {
    130                 if(mp[i][j] == '@')
    131                     EX = i,EY = j;
    132                 if(mp[i][j] >= '1' && mp[i][j] <= '9')
    133                 {
    134                     k = mp[i][j] - '0';
    135                     p[k].x = i,p[k].y = j;
    136                     K = max(K,k);
    137                 }
    138             }
    139         }
    140         S.num = p_to_num(p);
    141         S.x = p[1].x;
    142         S.y = p[1].y;
    143         S.step = 0;
    144         printf("Case #%d: %d
    ",cs++,BFS(S));
    145     }
    146     return 0;
    147 }
    代码君
      1 #include <map>
      2 #include <set>
      3 #include <list>
      4 #include <cmath>
      5 #include<cctype>
      6 #include <ctime>
      7 #include <deque>
      8 #include <stack>
      9 #include <queue>
     10 #include <cstdio>
     11 #include <string>
     12 #include <vector>
     13 #include <cstdlib>
     14 #include <cstring>
     15 #include <iostream>
     16 #include <algorithm>
     17 #define LL long long
     18 #define PI 3.1415926535897932626
     19 using namespace std;
     20 int gcd(int a, int b)
     21 {
     22     return a % b == 0 ? b : gcd(b, a % b);
     23 }
     24 char G[20][20];
     25 int vis[20000000];
     26 int dx[]={1,0,-1,0};
     27 int dy[]={0,1,0,-1};
     28 int len;
     29 int N,M;
     30 int e_x,e_y,s_x,s_y;
     31 int ans;
     32 struct node
     33 {
     34     int x[11],y[11];//存蛇的每一个点的横纵坐标
     35     int dist;
     36 }s;
     37 queue<node>Q;
     38 int get_nextdir(int cur,int pre,node s)
     39 {
     40     for (int d=0;d<4;d++)
     41     {
     42         int nx=s.x[pre]+dx[d];
     43         int ny=s.y[pre]+dy[d];
     44         if (nx==s.x[cur] && ny==s.y[cur]) return d;
     45     }
     46 }
     47 int hash(int x,int y,node s)
     48 {
     49     int Hash=x*M+y;
     50     for (int i=1;i<len;i++)
     51         {
     52             Hash=Hash*4+get_nextdir(i,i-1,s);
     53         }
     54         return (Hash%20000000);
     55 }
     56 void read()
     57 {
     58     len=0;
     59     ans=-1;
     60     memset(G,0,sizeof(G));
     61     memset(vis,0,sizeof(vis));
     62     for (int i=0;i<N;i++)
     63     scanf("%s",G[i]);
     64     for (int i=0;i<N;i++)
     65         for (int j=0;j<M;j++)
     66     {
     67         if (G[i][j]=='@') {e_x=i;e_y=j;}
     68         if (isdigit(G[i][j]))
     69         {
     70             if (G[i][j]=='1') {s_x=i;s_y=j;}
     71             s.x[G[i][j]-'1']=i;
     72             s.y[G[i][j]-'1']=j;
     73             G[i][j]='.';
     74             len++;
     75         }
     76     }
     77     s.dist=0;
     78     int T=hash(s_x,s_y,s);
     79     vis[T]=1;
     80     Q.push(s);
     81     //show();
     82 }
     83 void bfs()
     84 {
     85     while (!Q.empty())
     86     {
     87         node u=Q.front();
     88         Q.pop();
     89         if (u.x[0]==e_x && u.y[0]==e_y) {ans=u.dist;return ;}
     90         int x=u.x[0],y=u.y[0];
     91         for (int d=0;d<4;d++)
     92         {
     93             int nx=x+dx[d];
     94             int ny=y+dy[d];
     95             if (nx<0 || nx>=N || ny<0 || ny>=M || G[nx][ny]=='#') continue;
     96             bool flag=false;
     97             if (len>=3)
     98             {
     99              for (int i=1;i<len-1;i++)
    100              if (nx==u.x[i] && ny==u.y[i]) {flag=true;break;}
    101              if (flag) continue;
    102              node s;
    103              s.x[0]=nx;s.y[0]=ny;
    104              for (int i=1;i<len;i++)
    105              {
    106                 s.x[i]=u.x[i-1];
    107                 s.y[i]=u.y[i-1];
    108              }
    109              LL T=hash(nx,ny,s);
    110              if (!vis[T])
    111              {
    112                 vis[T]=1;
    113                 s.dist=u.dist+1;
    114                 Q.push(s);
    115              }
    116             }
    117             else
    118             {
    119                 for (int i=1;i<=len-1;i++)//注意和上一种i<len-1不同
    120              if (nx==u.x[i] && ny==u.y[i]) {flag=true;break;}
    121              if (flag) continue;
    122              node s;
    123              s.x[0]=nx;s.y[0]=ny;
    124              for (int i=1;i<len;i++)
    125              {
    126                 s.x[i]=u.x[i-1];
    127                 s.y[i]=u.y[i-1];
    128              }
    129              LL T=hash(nx,ny,s);
    130              if (!vis[T])
    131              {
    132                 vis[T]=1;
    133                 s.dist=u.dist+1;
    134                 Q.push(s);
    135              }
    136             }
    137         }
    138     }
    139 }
    140 int main()
    141 {
    142     //freopen("sample.txt","r",stdin);
    143     int kase=1;
    144     while (scanf("%d%d",&N,&M)!=EOF)
    145     {
    146         read();
    147         bfs();
    148         printf("Case #%d: %d
    ",kase++,ans);
    149         while (!Q.empty())Q.pop();
    150     }
    151     return 0;
    152 }
    哈希版
  • 相关阅读:
    (第二周)效能测试
    (第二周)新小学四则运算
    (第二周)项目点评
    (第二周)通读《构建之法》有感
    (第二周)scrum站立会议
    (第二周) 燃尽图
    (第一周)工作总结
    (第一周)小学四则运算
    软件工程第三次作业
    软件工程第二次作业
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4265873.html
Copyright © 2020-2023  润新知