zoukankan      html  css  js  c++  java
  • Luogu P3818 小A和uim之dark♂逃离 Ⅱ

    沉迷分层图无法自拔......

    这道题,首先一看,不就是个BFS走迷宫嘛,一本通上都有讲过

    然后,诶怎么还有上一次的魔液(诶原来魔液是干这个用的

    然后就想到,「诶,魔液只能用一次......那就用0/1表示没有用/用过,就行了吧」

    然后就开始......

    建图......(诶我真是丧心病狂)

    用三个数字x,y,z表示某个点的坐标,z=0表示在第一层(没有喝过),z=1表示在第二层(喝过了)

    在原有两层正常图的基础上,喝魔液相当于连一条从图层0到图层1的,起点为 $ (x,y,0) $ ,终点为 $ (x+d,y+r,1) $ 的边。

    建完图之后从起点开始跑一遍SPFA,取 $ min(d[n][m][0],d[n][m][1]) $ 即为答案。

    思路出来了,十分钟敲完了代码,兴高采烈拿去试样例......结果第三个样例WA了,输出13正解21

    (话说这道题的样例还是很良心的,不像某些题的样例不具有特殊性,查不出错)

    为什么会少呢......肯定是抄近路了

    于是便开始输出中间结果调试

    果不其然,数组从0到n,0到m,而出发点是在(1,1),我特判没写好,导致可以从x=0或y=0的「不存在的地方」抄近路过去

    形象化来说就是走地图边偷家

    改了之后就一遍A了

    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    int a[1005][1005];
    int n,m,d,r;
    
    struct node{
    	int x,y,z;
    	node(int x=0,int y=0,int z=0):
    		x(x),y(y),z(z){
    			
    		}
    };
    
    bool ok(int x,int y){
    	if(x<1 or x>n or y<1 or y>m)return 0;
    	return 1;
    }
    int f[1005][1005][2];
    
    bool vis=0;
    void bfs(){
    	bool inq[1005][1005][2];
    	memset(inq,0,sizeof inq);
    	memset(f,0x3f3f,sizeof f);
    	queue<node>q;
    	f[1][1][0]=0;
    	q.push(node(1,1,0));
    	inq[1][1][0]=1;
    	while(!q.empty()){
    		node u=q.front();
    		int x=u.x,y=u.y,z=u.z;
    		inq[x][y][z]=0;
    		q.pop();
    		if(x<1 or x>n or y<1 or y>m)continue;
    		if(ok(x+1,y) and f[x+1][y][z]>f[x][y][z]+1 and !a[x+1][y]){
    			f[x+1][y][z]=f[x][y][z]+1;
    			if(x+1==n and y==m)vis=1;
    			if(!inq[x+1][y][z]){
    				inq[x+1][y][z]=1;
    				q.push(node(x+1,y,z));
    			}
    		}
    		if(ok(x-1,y) and f[x-1][y][z]>f[x][y][z]+1 and !a[x-1][y]){
    			f[x-1][y][z]=f[x][y][z]+1;
    			if(x-1==n and y==m)vis=1;
    			if(!inq[x-1][y][z]){
    				inq[x-1][y][z]=1;
    				q.push(node(x-1,y,z));
    			}
    		}
    		if(ok(x,y+1) and f[x][y+1][z]>f[x][y][z]+1 and !a[x][y+1]){
    			f[x][y+1][z]=f[x][y][z]+1;
    			if(x==n and y+1==m)vis=1;
    			if(!inq[x][y+1][z]){
    				inq[x][y+1][z]=1;
    				q.push(node(x,y+1,z));
    			}
    		}
    		if(ok(x,y-1) and f[x][y-1][z]>f[x][y][z]+1 and !a[x][y-1]){
    			f[x][y-1][z]=f[x][y][z]+1;
    			if(x==n and y-1==m)vis=1;
    			if(!inq[x][y-1][z]){
    				inq[x][y-1][z]=1;
    				q.push(node(x,y-1,z));
    			}
    		}
    		if(ok(x+d,y+r) and z==0 and f[x+d][y+r][1]>f[x][y][0]+1 and !a[x+d][y+r]){
    			f[x+d][y+r][1]=f[x][y][0]+1;
    			if(x+d==n and y+r==m)vis=1;
    			if(!inq[x+d][y+r][1]){
    				inq[x+d][y+r][1]=1;
    				q.push(node(x+d,y+r,1));
    			}
    		}
    	}
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&d,&r);
    	for(int i(1);i<=n;i++){
    		for(int j(1);j<=m;j++){
    			char in;cin>>in;
    			if(in=='#')a[i][j]=1;
    		}
    	}
    	bfs();
    	if(!vis){
    		cout<<-1;
    		return 0;
    	}
    	printf("%d",min(f[n][m][0],f[n][m][1]));
    	return 0;
    }
    
    
  • 相关阅读:
    新浪微博 js 解密
    新浪微博、qq rsa密码加密c#实现
    C#版本的discuz authcode函数
    搬地方了,在github弄了个新博客
    python 发送邮件
    通用网页广告监测,ADBlock plus算法的C#实现。
    58同城登录 c#,非直接操作js
    python模块之smtplib: 用python发送SSL/TLS安全邮件
    Python少打字小技巧
    python模块之poplib: 用pop3收取邮件
  • 原文地址:https://www.cnblogs.com/soul-M/p/9589972.html
Copyright © 2011-2022 走看看