• hdu 1010 解题报告 Tempter of the Bone


    hdu 1010 解题报告 ----Tempter of the Bone

    题意:输入一个n*m的迷宫,和一个T:可以在迷宫中生存的最大时间。S为起点,D为终点。并且,每个格子只能踩一次,且只能维持一秒,然后该块地板就会塌陷。所以你必须每秒走一步,且到D点时,所用时间为T。用深搜。

    本题要点:看是否能在所有可能的路中找到刚好满足条件(到达终点时门恰好打开)的路程,本题需要注意,单用深搜会超时,所以,有一个剪枝的地方非常重要!!!


    本来写的是java版,但不知为何提交不了就还原陈了C++版

    C++版:

     

    Problem : 1010 ( Tempter of the Bone )     Judge Status : Accepted
    RunId : 8246601    Language : C++    Author : luotianyu520
    Code Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta
    #include<iostream>  
    using namespace std;  
    int sx,sy,ex,ey;  //起点和终点坐标
    int n,m;  //迷宫的行数列数
    char map[10][10];// 迷宫
    int flag;//判断成功
    int d[4][2]={0,1,1,0,0,-1,-1,0};  // 下、右、上、左
    void dfs(int x,int y,int t)  
    {   
        /** 1、排除并剪枝 */
        if(flag==1) return ;// 成功则返回
        // 剩余时间不足以走到终点 或者 当前点与终点横纵坐标差的和 与 剩余时间之差奇偶性不同。则直接否决返回
        if(t<abs(ex-x)+abs(ey-y)||(t-abs(ex-x)+abs(ey-y))%2) return ; 
        // 时间用完,则判断是否到终点并返回
        if(t==0) 
        {
            if(x==ex&&y==ey)  {flag=1; return ;}
            else { return ;  }
        }
        /** 2、递归四个方向 */
        for(int i=0;i<4;i++)                 
        {
            int nx=x+d[i][0],ny=y+d[i][1];//下一位置
            // 排除:1越界,2不是'.'或不是终点
            if (nx>0&&nx<=n&&ny>0&&ny<=m&&(map[nx][ny]=='.'||map[nx][ny]=='D'))
            {
                map[nx][ny]='X';//标记当前点走过         
                dfs( nx,ny,t-1) ;// 时间-1,递归下一点
                map[nx][ny]='.';//还原状态         
            }
    
        }  
        return ;  
    }  
    int main()  
    {  
    
    
        char str[10];    
        int t;  
        while (scanf("%d%d%d",&n,&m,&t)!=EOF)  
        {     
            if(n==0&&m==0&&t==0) return 0;  
            for (int i=1;i<=n;i++)  
            {  
                scanf("%s",str);  
                for (int j=1;j<=m;j++)  
                {  
                    map[i][j]=str[j-1];     
                    if(map[i][j]=='S')  sx=i,sy=j;  
                    else if(map[i][j]=='D') ex=i,ey=j;  
                }  
            }           
            flag=0;  
            dfs(sx,sy,t);  
            if(flag==0) printf("NO\n");  
            else printf("YES\n");   
        }  
        return 0;  
    }
    #include<iostream>  
    using namespace std;  
    int sx,sy,ex,ey;  //起点和终点坐标
    int n,m;  //迷宫的行数列数
    char map[10][10];// 迷宫
    int flag;//判断成功
    int d[4][2]={0,1,1,0,0,-1,-1,0};  // 下、右、上、左
    void dfs(int x,int y,int t)  
    {   
        /** 1、排除并剪枝 */
        if(flag==1) return ;// 成功则返回
        // 剩余时间不足以走到终点 或者 当前点与终点横纵坐标差的和 与 剩余时间之差奇偶性不同。则直接否决返回
        if(t<abs(ex-x)+abs(ey-y)||(t-abs(ex-x)+abs(ey-y))%2) return ; 
        // 时间用完,则判断是否到终点并返回
        if(t==0) 
        {
            if(x==ex&&y==ey)  {flag=1; return ;}
            else { return ;  }
        }
        /** 2、递归四个方向 */
        for(int i=0;i<4;i++)                 
        {
            int nx=x+d[i][0],ny=y+d[i][1];//下一位置
            // 排除:1越界,2不是'.'或不是终点
            if (nx>0&&nx<=n&&ny>0&&ny<=m&&(map[nx][ny]=='.'||map[nx][ny]=='D'))
            {
                map[nx][ny]='X';//标记当前点走过         
                dfs( nx,ny,t-1) ;// 时间-1,递归下一点
                map[nx][ny]='.';//还原状态         
            }
    
        }  
        return ;  
    }  
    int main()  
    {  
    
    
        char str[10];    
        int t;  
        while (scanf("%d%d%d",&n,&m,&t)!=EOF)  
        {     
            if(n==0&&m==0&&t==0) return 0;  
            for (int i=1;i<=n;i++)  
            {  
                scanf("%s",str);  
                for (int j=1;j<=m;j++)  
                {  
                    map[i][j]=str[j-1];     
                    if(map[i][j]=='S')  sx=i,sy=j;  
                    else if(map[i][j]=='D') ex=i,ey=j;  
                }  
            }           
            flag=0;  
            dfs(sx,sy,t);  
            if(flag==0) printf("NO\n");  
            else printf("YES\n");   
        }  
        return 0;  
    }
    

    Java版(答案没问题,可惜就是不知道哪不对,若有人找到不胜感激):

     

    package code.part3.problem;
    
    import java.util.Scanner;
    
    public class Main {
    	static Scanner scanner = new Scanner(System.in);
    	static int n, m, time;// 迷宫的行,列,时间
    	static char[][] map = new char[105][105];// 迷宫
    	static Point start = new Point(), end = new Point();// 起点、终点
    	static int[][] move = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };// 下、右、上、左
    	static boolean flag = false;
    
    	private static class Point {
    		int x;
    		int y;
    	}
    
    	public static void main(String args[]) {
    		while (scanner.hasNextInt()) {
    			n = scanner.nextInt();
    			m = scanner.nextInt();
    			time = scanner.nextInt();
    			if (n <= 1 || m >= 7 || time >= 50)
    				return;
    
    			init();
    			dfs(start, time);
    			
    			if (flag)	System.out.printf("YES\n");
    			else	System.out.printf("NO\n");
    		}
    		scanner.close();
    	}
    
    	public static void init() {
    		flag = false;
    		for (int i = 0; i < n; i++) {
    			map[i] = scanner.next().toCharArray();
    			for (int j = 0; j < m; j++) {
    				if (map[i][j] == 'S') {
    					start.x = i;
    					start.y = j;
    				} else if (map[i][j] == 'D') {
    					end.x = i;
    					end.y = j;
    				}
    			}
    		}
    	}
    
    	public static void dfs(Point fromP, int time) {
    		/** 1、排除并剪枝 */
    		// 成功则返回
    		if (flag)
    			return;
    		// 剩余时间不足以走到终点 或者 当前点与终点横纵坐标差的和 与 剩余时间之差奇偶性不同。则直接否决返回
    		if (time < Math.abs(end.x - fromP.x) + Math.abs(end.y - fromP.y)
    				|| (time - Math.abs(end.x - fromP.x) + Math
    						.abs(end.y + fromP.y)) % 2 == 1)
    			return;
    		// 时间用完,则判断是否到终点并返回
    		if (time == 0) {
    			if (fromP.x != end.x || fromP.y != end.y)
    				return;
    			flag = true;
    			return;
    		}
    
    		/** 2、递归四个方向 */
    		for (int i = 0; i < 4; i++) {
    			Point toP = new Point();
    			// 新位置
    			toP.x = fromP.x + move[i][0];
    			toP.y = fromP.y + move[i][1];
    			// 排除:1越界,2不是'.'或不是终点,直接下一个
    			if (toP.x < 0 || toP.y < 0 || toP.x >= n || toP.y >= m
    					|| (map[toP.x][toP.y] != '.' && map[toP.x][toP.y] != 'D'))
    				continue;
    			map[toP.x][toP.y] = 'X';// 标记当前点走过
    			dfs(toP, time - 1);// 时间-1,递归下一点
    			map[toP.x][toP.y] = '.';// 还原状态
    		}
    	}
    }
  • 相关阅读:
    1058 A+B in Hogwarts (20)
    1046 Shortest Distance (20)
    1061 Dating (20)
    1041 Be Unique (20)
    1015 Reversible Primes (20)(20 分)
    pat 1027 Colors in Mars (20)
    PAT 1008 Elevator (20)
    操作系统 死锁
    Ajax的get方式传值 避免& 与= 号
    让IE浏览器支持CSS3表现
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3063521.html
Copyright © 2020-2023  润新知