首页 > 代码库 > uestc 贪吃蛇

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\n",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             else118             {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\n",kase++,ans);149         while (!Q.empty())Q.pop();150     }151     return 0;152 }
哈希版

 

uestc 贪吃蛇