• day 1 T1 迷宫


    迷宫

    【问题描述】
    n*m 的迷宫, 迷宫中有 k 种钥匙, 每个格子有一个整数 x, 如果 x=0 说明可
    以任意到达, |x|>k 代表不允许到达。 x>0 代表该位置有第 x 种钥匙, 捡起地上的
    钥匙需要花费 1 步。 x<0 代表到达该位置需要第-x 种钥匙, 开门不需要时间, 问
    从左上角走到右下角最少需要多少步? (数据保证左上角是 0)
    【输入格式】
    第一行三个正整数 n,m,k
    接下来 n 行, 每行 m 个整数表示地图
    【输出格式】
    输出一个整数, 表示从左上角走到右下角最少需要多少步, 若不能到达输出-1.
    【样例输入】
    3 5 2
    0 0 0 0 0
    2 3 0 0 -1
    3 1 -2 3 0
    【样例输出】
    14
    【数据解释】
    先拿到第 2 把钥匙, 然后再拿第 3 把钥匙
    【数据规模与约定】
    20% n,m<=10 k<=2
    另 30% n,m<=1000 k=0
    100% n,m<=1000 k<=5
    

    代码及解析

    #include<queue>
    #include<cstdio>
    #include<algorithm>
    #define N 1005
    using namespace std;
    int n,m,k;
    int map[N][N];
    struct node{int x,y,s,dis;};
    queue<node>q;
    bool vis[N][N][32];//第三维有2^5种可能性(最多5把钥匙) 
    int dx[]={0,0,-1,1}; 
    int dy[]={1,-1,0,0};
    int main()
    {
    //	freopen("maze.in","r",stdin);
    //	freopen("maze.out","w",stdout);
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=m;j++)
    	scanf("%d",&map[i][j]);//存图 
    	q.push((node){1,1,0,0});//依次为坐标x,y,钥匙状态,步数 
    	while(!q.empty())//bfs开始 
    	{
    		node tmp=q.front();q.pop();
    		if(tmp.x==n&&tmp.y==m)//找到即结束程序 
    		{
    			printf("%d
    ",tmp.dis);
    			return 0;
    		}
    		if(map[tmp.x][tmp.y]>0)//有钥匙 ,则会有第五种操作(当然不会是死路,死路不会入队 ……45行) 
    		{
    			int s=tmp.s|(1<<(map[tmp.x][tmp.y]-1));
    			//这一步神来之笔, 1<<(map[tmp.x][tmp.y]-1)表示钥匙的状态  与当前钥匙取并集 
    			if(!vis[tmp.x][tmp.y][s])//如果这个状态还没有过 
    			{
    				vis[tmp.x][tmp.y][s]=1;
    				q.push((node){tmp.x,tmp.y,s,tmp.dis+1});//把这个状态更新到队列中,步数+1 
    			}
    		}
    		for(int z=0;z<4;z++)
    		{
    			int x=tmp.x+dx[z];
    			int y=tmp.y+dy[z];
    			int s=tmp.s;
    			if(x<1||x>n||y<1||y>m)continue;//出图不入队 
    			if(map[x][y]>k)continue;//死路不入队 
    			if(map[x][y]<0&&!((1<<(-map[x][y]-1))&s))continue;
    			//注意这个地方是负数,要取相反数 
    			//还没拿到钥匙的不入队 ,拿到钥匙了就直接入队了,不消耗钥匙,所以不必单判 
    			if(!vis[x][y][s])
    			//这个位置还没走过的话入队(以前可能经过过这个点,但这次我拿钥匙来了也算没来过,入队) 
    			{
    				vis[x][y][s]=1;
    				q.push((node){x,y,s,tmp.dis+1});
    			}
    		}
    	}
    	puts("-1");//华丽地结束,搜不到 
    }
  • 相关阅读:
    ZooKeeper入门(二)Java API开发实战
    mysql 通过存储过程添加分表和分表的字段
    Mysql 事务隔离级别以及相关概念
    一个替代npm和cnpm的方案:pnpm
    【速学】TypeScript学习记录
    true和false,truthy和Falsy
    resolve的意思是解析、解决、决定,assign是指派、赋值的意思
    更换node版本一定要记得删掉nodemodules
    【换平台】从admin来看React转Vue
    【typescript】写给JS老鸟的TS速成教程
  • 原文地址:https://www.cnblogs.com/baikou/p/12204073.html
Copyright © 2020-2023  润新知