完美世界2017/9/26笔试题

黄金圣斗士欧洛斯要去圣域救雅典娜,需要从左上角出发,每次只能向右或向下走,最后到右下角见到雅典娜。地图中每个位置代表圣斗士遭遇的事情,如果是负数,说明此处有狙击,要让盛都欧式损失血量,如果是非负数,说明此处有血瓶,能让圣斗士回血,圣斗士从左上角到右下角的过程中,走到任何一个位置是,血量都不能少于1,为了保证圣斗士能救出雅典娜,初始血量至少为多少?地图为一个二维数组map,如下矩阵,根据map返回初始血量。

-2   -3   3

-5   -10  1

0   30   -5

返回7


思路是这样的:

从左上角到右下角有n条路径,求每条路径上最大耗血量,这n个耗血量中的最小耗血量+1即为初始血量。

因为每一步都要求血量最少为1,设初始血量为-1,从map[0][0]到map[n][m]做加法,记录这个累加过程中的最小值(一定是负数,且最大为-1)。

到达map[n][m]的时候比较这条路径的累加最小值min和以前的最大的累加最小值max,二者取大值存入max

最后所求血量即为-1*max



import java.util.Scanner;

public class MyTest2 {
	static int max=-1;
	static boolean flag=true;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int[][]map=new int[n][m];
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				map[i][j]=sc.nextInt();
			}
		}	
		minblood(map,n-1,m-1,-1,0,0,-1);
		int ans=-1*max;
        System.out.println(ans);
	}

	private static void minblood(int[][] map,int n,int m,int curr,int midn,int midm,int min) {
		curr=curr+map[midn][midm];
    		min=Math.min(min, curr);
    if(midn==n&&midm<m){//到达行边界未到列边界   
    	minblood(map,n,m,curr,midn,midm+1,min);
    }else if(midm==m&&midn<n){ //到达列边界未到行边界   	
    	minblood(map,n,m,curr,midn+1,midm,min);
    }else if(midn==n&&midm==m){//到行列边界
    	if(flag){//第一次到达右下角
    		max=min;
    		flag=false;
    	}else{
    		max=Math.max(min,max);
    	}    
    }else{ //未到达边界 	
    	minblood(map,n,m,curr,midn+1,midm,min);
    	minblood(map,n,m,curr,midn,midm+1,min);
    }
	}

}
/*
 * 
 3 3
-2 -3 3 -5 -10 1 0 30 -5

3 3
0 -1 -1 0 -1 -1 0 0 0

2 2
1 1 1 1

2 2
-1 0 0 -1
*/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值