zoukankan      html  css  js  c++  java
  • hdu1885 Key Task

    刚开始看到这题都吓到了,第一感觉就是不能记录已走过的点,一旦记录了,那假设钥匙在对面,门在这边,那拿完钥匙就回不来了;

    可是,如果不记录的话,那岂不是在整个地图了乱窜,绝对超时,甚至是死循环;

    之后,想了想,把每个点在入队列的时候,记录下状态每一个点的状态,即又有没有拿到钥匙,拿到哪几种钥匙之类的,如果回溯时,俩点的状态一样,则没必要入队,这确实是一种可行的办法,可是想到这里,突然,想到,要对每一个点保存16种状态,那内存肯定要爆了呀,结果思路就这么停了,想不出别的办法了……

    查了一下,原来记录状态是用位运算保存呀,郁闷呐,亏我知道这东西存在,亏我还用过位运算保存过一个数字是否出现过,结果我居然一点都没想到,惭愧呀

    是这样保存的,开一个三维的数组,flag[101][101][16],记录每一个点的状态,除了坐标之外,保存的是一个点有没有钥匙,有多少把钥匙,每一个位保存一把钥匙的状态,总共十六种状态

    假设 // b,y,r, g 钥匙分别用二进制的第一,二,三,四位保存,flag&1 ==1 表示 该状态b钥匙已经有了,当拿到b钥匙时,flag|=1,记录下来。

    #include<iostream>
    #include<queue>
    using namespace std;
    char map[101][101];
    int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}},n,m;
    int flag[101][101][16];
    // b,y,r, g: 1,2,4,8
    struct node
    {
    	int x,y,cnt,v;
    	node(int _x=0,int _y=0,int _cnt=0 ,int _v=0):x(_x),y(_y),cnt(_cnt),v(_v){};
    	friend bool operator <(const node &a,const node &b)
    	{
    		return a.cnt>b.cnt;
    	}
    };
    node f;
    bool OK(int i,int j,int va)
    {
    	if(map[i][j]=='B'&&(va&1))
    		return true;
    	if(map[i][j]=='Y'&&(va&2))
    		return true;
    	if(map[i][j]=='R'&&(va&4))
    		return true;
    	if(map[i][j]=='G'&&(va&8))
    		return true;
    	return false;
    }
    int bfs()
    {
    	flag[f.x][f.y][f.v]=1;
    	priority_queue<node> Q;
    	Q.push(f);
    	while(!Q.empty())
    	{
    		node t=Q.top();
    		Q.pop();
    		for(int k=0;k<4;k++)
    		{
    			int i=t.x+dir[k][0];
    			int j=t.y+dir[k][1];
    			if(i<n&&i>=0&&j<m&&j>=0&&map[i][j]!='#')
    			{
    				if(OK(i,j,t.v)&&!flag[i][j][t.v])
    				{
    					flag[i][j][t.v]=1;
    					Q.push(node(i,j,t.cnt+1,t.v));
    				}
    				else if(map[i][j]=='b'&&!flag[i][j][t.v|1])
    				{
    					flag[i][j][t.v|1]=1;
    					Q.push(node(i,j,t.cnt+1,t.v|1));
    				}
    				else if(map[i][j]=='y'&&!flag[i][j][t.v|2])
    				{
    					flag[i][j][t.v|2]=1;
    					Q.push(node(i,j,t.cnt+1,t.v|2));
    				}
    				else if(map[i][j]=='r'&&!flag[i][j][t.v|4])
    				{
    					flag[i][j][t.v|4]=1;
    					Q.push(node(i,j,t.cnt+1,t.v|4));
    				}
    				else if(map[i][j]=='g'&&!flag[i][j][t.v|8])
    				{
    					flag[i][j][t.v|8]=1;
    					Q.push(node(i,j,t.cnt+1,t.v|8));
    				}
    				else if(map[i][j]=='.'&&!flag[i][j][t.v])
    				{
    					flag[i][j][t.v]=1;
    					Q.push(node(i,j,t.cnt+1,t.v));
    				}
    				else if(map[i][j]=='X')
    					return t.cnt+1;
    			}
    		}
    	}
    		return 0;
    }
    int main()
    {
    	while(cin>>n>>m&&(n||m))
    	{
    		for(int i=0;i<n;i++)
    			for(int j=0;j<m;j++)
    			{
    				cin>>map[i][j];
    				if(map[i][j]=='*')
    					f.x=i,f.y=j;
    			}
    		f.cnt=0;f.v=0;map[f.x][f.y]='.';
    		memset(flag,0,sizeof(flag));
    		int t=bfs();
    		if(t)
    		cout<<"Escape possible in "<<t<<" steps."<<endl;
    		else cout<<"The poor student is trapped!"<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    CSS快速入门
    Kafka (一) 核心概念
    软件工程模型
    函数式编程
    spark计算操作整理
    HBase 文件合并
    HBase 数据存储结构
    目的论浅谈
    PHP8的注解
    JS的移入移除
  • 原文地址:https://www.cnblogs.com/nanke/p/2128441.html
Copyright © 2011-2022 走看看