C語言實現 藍橋杯 算法訓練 步與血

試題 算法訓練 步與血

                                                                                  藍橋杯試題解答彙總鏈接

資源限制

       時間限制:1.0s 內存限制:256.0MB


問題描述

       有n×n的方格,其中有m個障礙,第i個障礙會消耗你p[i]點血。初始你有C點血,你需要從(1,1)到(n,n),並保證血量大於0,求最小步數。


輸入格式

       第一行3個整數n,m,c,表示棋盤大小、障礙數量和你的血量
  接下來m行,每行描述一個障礙。包含三個整數x y p,分別表示障礙在第x行第y列,消耗血量爲p。


輸出格式

       如果可以到輸出步數,如果不可以,輸出"No"。


樣例輸入

10 10 10
2 8 35
1 10 25
9 9 63
5 6 46
2 6 43
8 7 92
5 3 54
3 3 22
7 9 96
9 10 13

樣例輸出

18

數據規模與約定

輸入數據中每一個數的範圍。
0<n,m<100,

試題解析

步數最小就得每次只能向下或向右走,那麼這樣就很容易取動態規劃了設dp.co[i][j]爲走到(i,j)位置需要的步數那麼dp.co[i][j]=min(dp.co[i-1][j],dp.co[i][j-1])但其中有障礙所以還需要保存到每個位置的血量>0,否則說明這個點不能走


代碼

#include <stdio.h>
typedef struct s{
	int co[101][101];// 走到(i,j)需要的最小步數 
	int blood[101][101];// 走到(i,j)剩餘的血量 
}step;
int main() {// n、m、c、x、y、p對應題意 
	int n, m, c, x, y, p, i, j;
	scanf("%d%d%d",&n,&m,&c);
	int chess[101][101] = {0};// 棋盤chess的值爲此處消耗的血量 
	for(i = 0;i < m; ++i) {
		scanf("%d%d%d",&x,&y,&p);
		chess[x][y] = p;
	}
	step dp;
	dp.blood[1][1] = c;// 初始化血量 
	dp.co[1][1] = 0;// 初始化步數 
	for(i = 2;i <= n; ++i) {// 初始化第一行第一列 
		dp.co[1][i] = dp.co[1][i-1]+1;// 從(1,i-1)到(1,i)步數+1 
		dp.blood[1][i] = dp.blood[1][i-1]-chess[1][i];// 去掉消耗的血量 
		if(dp.blood[1][i] <= 0) {// 血量不大於0說明這裏不能走步數設爲0 
			dp.co[1][i] = 0;
		}
		dp.co[i][1] = dp.co[i-1][1]+1;
		dp.blood[i][1] = dp.blood[i-1][1]-chess[i][1];
		if(dp.blood[i][1] <= 0) {
			dp.co[i][1] = 0;
		}
	}
	for(i = 2;i <= n; ++i) {// 從(2,2)開始遞推 
		for(j = 2;j <= n; ++j) {
			if(dp.co[i-1][j]>0 && dp.co[i][j-1]>0) {// 左邊和上邊步數不爲0說明都能通行 
				if(dp.co[i-1][j] <= dp.co[i][j-1]) {
					dp.co[i][j] = dp.co[i-1][j]+1;
					dp.blood[i][j] = dp.blood[i-1][j]-chess[i][j];
					if(dp.blood[i][j] <= 0) {
						dp.co[i][j] = 0;
					}
				}else {
					dp.co[i][j] = dp.co[i][j-1]+1;
					dp.blood[i][j] = dp.blood[i][j-1]-chess[i][j];
					if(dp.blood[i][j] <= 0) {
						dp.co[i][j] = 0;
					}
				}
			}else if(dp.co[i-1][j] == 0) {// 有一個爲0取另外一個 
				dp.co[i][j] = dp.co[i][j-1]+1;
				dp.blood[i][j] = dp.blood[i][j-1]-chess[i][j];
				if(dp.blood[i][j] <= 0) {
						dp.co[i][j] = 0;
				}
			}else{
				dp.co[i][j] = dp.co[i-1][j]+1;
				dp.blood[i][j] = dp.blood[i-1][j]-chess[i][j];
				if(dp.blood[i][j] <= 0) {
						dp.co[i][j] = 0;
				}
			}
		}
	}
	if(dp.blood[n][n] > 0) {
		printf("%d",dp.co[n][n]);
	}else {
		printf("No");
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章