• HDU-1072-Nightmares


    这题可以用dfs写,我们记忆化搜索。

    我们定义一个step和time数组,分别表示走到这点的最小步数,time表示走到该点炸弹还剩多少时间。

    递归边界一是,如果走到该点,时间等于0,我们就返回。

    如果走到了终点并且我们这次走到这点的最小步数小于了之前的答案,我们就更新答案并返回。

    剪枝,首先越界剪枝,然后我们走到一点,不能步数增加了,并且上一次我们走这点炸弹的剩余时间pre,小于这次的炸弹剩余时间now。

    那样的话,我们不如不走,我们还可以知道我们如果走到这点,步数和上一次相同,剩余时间也相同,我们就不必再搜这点,所以有两个等于。

    然后我们更新步数和时间,更新之后再来判断,此时我们走到下一个房间,是否能够重置时间,可以就重置。

    然后搜向下一个节点。

    #include <cstdio>
    #include <cstring>
    const int INF=0x3f3f3f3f;
    int map[10][10],step[10][10],time[10][10];
    int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    int n,m,ans;
    
    void dfs(int x,int y)
    {
    	if (time[x][y]<=0)
    		return;
    	if (map[x][y]==3) {
    		if (step[x][y]<ans)
    			ans=step[x][y];
    		return ;
    	}
    	for (int i=0;i<4;i++) {
    		int dx=x+d[i][0];
    		int dy=y+d[i][1];
    		if (dx>=0&&dy>=0&&dx<n&&dy<m&&map[dx][dy]) {
    			if (step[x][y]+1>=step[dx][dy]&&time[x][y]-1<=time[dx][dy])
    				continue;
    			step[dx][dy]=step[x][y]+1;
    			time[dx][dy]=time[x][y]-1;
    			if (map[dx][dy]==4&&time[dx][dy]>0)
    				time[dx][dy]=6;
    			dfs(dx,dy);
    		}
    	}
    }
    
    int main()
    {
    	int t,sx,sy;
    	scanf("%d",&t);
    	while (t--) {
    		scanf("%d%d",&n,&m);
    		for (int i=0;i<n;i++) {
    			for (int j=0;j<m;j++) {
    				scanf("%d",&map[i][j]);
    				if (map[i][j]==2)
    					sx=i,sy=j;
    			}
    		}
    		memset(time,0,sizeof(time));
    		memset(step,INF,sizeof(step));
    		ans=INF;
    		time[sx][sy]=6;
    		step[sx][sy]=0;
    		dfs(sx,sy);
    		printf("%d
    ",ans==INF?-1:ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    mysql创建和删除表
    性能测试工具curlloader(linux)
    Linux安装与硬盘分区
    linux那点事儿(上)
    Linux文件传输与mysql数据库安装
    性能测试工具curlloader二测试分析
    菜鸟学自动化测试(六)selenium 命令之文字范本匹配
    git/github初级运用自如
    开源自动化测试框架Tellurium
    菜鸟学自动化测试(五)selenium命令之定位页面元素
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10402820.html
Copyright © 2020-2023  润新知