zoukankan      html  css  js  c++  java
  • POJ 1324

    贪吃蛇问题,因为图的复杂性,为了空间效率,这时候就要考虑利用状态压缩来处理。

    算法倒是没有多复杂,但是非常考验码力,耐心,中间很多细节小错误(循环,判断顺序)

    开始状态压缩想的麻烦了,经过思考,将状态压缩集中到贪吃蛇形状,以及利用贪吃蛇的连贯性,就可以大大节省效率

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    typedef long long LL;
    const int maxn= 25;
    const int maxl= 11;
    
    struct Dox
    {
    	int hx, hy, bd;
    	int v;
    	Dox(int _hx= 0, int _hy= 0, int _bd= 0, int _v= 0) : hx(_hx), hy(_hy), bd(_bd), v(_v) {}
    };
    int n, m, l, k;
    int mz[maxn][maxn];
    int r[maxl], c[maxl], bd[maxl];
    int step[4][2]= {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};
    bool vis[maxn][maxn][(1<<14)+5];
    
    void Decode(int code[], int st, const int l)
    {
    	for (int i= 0; i< l; ++i){
    		code[i]= st & 3;
    		st>>= 2;
    	}
    }
    int Encode(int code[], const int l)
    {
    	int st= 0;
    	for (int i= l-1; i>= 0; --i){
    		st<<= 2;
    		st|= code[i];
    	}
    
    	return st;
    }
    int BFS()
    {
    	if (1== r[1] && 1== c[1]){
    		return 0;
    	}
    	for (int i= 1; i<= n; ++i){
    		for (int j= 1; j<= m; ++j){
    			memset(vis[i][j], 0, sizeof(vis[i][j]));
    		}
    	}
    	queue<Dox> Q;
    	int bd_s= Encode(bd+2, l-1);
    	int v= 0;
    	Q.push(Dox(r[1], c[1], bd_s, 0));
    	vis[r[1]][c[1]][bd_s]= 1;
    	Dox cur;
    
    	while (!Q.empty()){
    		cur= Q.front();
    		Q.pop();
    		Decode(bd+2, cur.bd, l-1);
    		r[1]= cur.hx;
    		c[1]= cur.hy;
    		v= cur.v+1;
    		for (int i= 2; i<= l; ++i){
    			r[i]= r[i-1]+step[bd[i]][0];
    			c[i]= c[i-1]+step[bd[i]][1];
    		}
    		for (int j= l; j> 2; --j){
    			bd[j]= bd[j-1];
    		}
    
    		for (int i= 0; i< 4; ++i){
    			int nx= r[1]+step[i][0], ny= c[1]+step[i][1];
    			int flag= 1;
    			if (1== nx && 1== ny){
    				return v;
    			}
    			if (nx< 1 || nx> n || ny< 1 || ny> m || mz[nx][ny]){
    				continue;
    			}
    			for (int j= 2; j<= l; ++j){
    				if (r[j]== nx && c[j]== ny){
    					flag= 0;
    					break;
    				}
    			}
    			if (flag){
    				bd[2]= 3-i;
    				bd_s= Encode(bd+2, l-1);
    				if (!vis[nx][ny][bd_s]){
    					Q.push(Dox(nx, ny, bd_s, v));
    					vis[nx][ny][bd_s]= 1;
    				}
    			}
    		}
    	}
    
    	return -1;
    }
    
    int main()
    {
    	int x, y;
    	int kase= 0;
    	while (~scanf("%d %d %d", &n, &m, &l) && n){
    		memset(mz, 0, sizeof(mz));
    		for (int i= 1; i<= l; ++i){
    			scanf("%d %d", r+i, c+i);
    		}
    		for (int i= l; i> 1; --i){
    			int dr= r[i]-r[i-1], dc= c[i]-c[i-1];
    			if (1== dr){
    				bd[i]= 0;
    			}
    			else if (-1== dr){
    				bd[i]= 3;
    			}
    			else if (1== dc){
    				bd[i]= 1;
    			}
    			else if (-1== dc){
    				bd[i]= 2;
    			}
    		}
    		scanf("%d", &k);
    		for (int i= 0; i< k; ++i){
    			scanf("%d %d", &x, &y);
    			mz[x][y]= 1;
    		}
    		printf("Case %d: %d
    ", ++kase, BFS());
    	}
    	return 0;
    }
    
  • 相关阅读:
    Web前端学习第五天——————HTML篇.019页面布局练习
    1111
    开发者如何利用数据分析提高收入
    开发者进行广告合作的几大误区
    高仿人人Android梦想版终极源码发送(转)
    移动开发者如何获取免费流量
    Inno setup常用代码【收藏】
    Inno setup常用代码补充【收藏】
    QT for Window程序部署
    Inno Setup自定义卸载文件名称【收藏】
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14677702.html
Copyright © 2011-2022 走看看