完美世界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
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章