资源限制
时间限制: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,
解题方法:
本题问的是最少的步数,在满足到(n,n)位置血量大于0的情况下,步数就是2*(n-1),步数最少就是:不是向左走就是向下走,不回头即可。
利用max函数,每一步都保证了在到达(i,j)位置时,血量都是最大的,即可以理解为走了耗血量最少的路径。
例如上图blood(2,2)=5,说明从(1,1)的位置是向右走的,而不是向下走的。
详细见程序注释。
源程序:
#include<iostream>
#include<string>
#include<algorithm>//max函数的头文件
using namespace std;
#define maxsize 100
int chessboard[maxsize][maxsize];//棋盘,其中存储着对应位置的耗血量
int blood[maxsize][maxsize];//在某位置时的剩余血量
void init(int m)//初始化棋盘
{
//memset(chessboard, 0, sizeof(chessboard));注释不注释都可以
//memset(blood, 0, sizeof(blood));
int x, y, p;
for (int i = 0; i < m; i++)//耗血量及对应的位置
{
cin >> x >> y >> p;
chessboard[x][y] = p;
}
}
bool judge(int n, int m, int c)//判断在n,n位置的血量
{
int x, y;
blood[1][1] = c - chessboard[1][1];//初始血量
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
//向下走:
//从(i-1,j)的位置走到(i,j)的位置
x = i - 1;
y = j;
if ((x >= 1 && x <= n) && (y >= 1 && y <= n) && blood[x][y] - chessboard[i][j] > 0)
blood[i][j] = max(blood[i][j], blood[x][y] - chessboard[i][j]);//获取最大血量值(即最优解路线)
//向右走:
//从(i,j-1)的位置走到(i,j)的位置
x = i;
y = j - 1;
if ((x >= 1 && x <= n) && (y >= 1 && y <= n) && blood[x][y] - chessboard[i][j] > 0)
blood[i][j] = max(blood[i][j], blood[x][y] - chessboard[i][j]);
}
}
if (blood[n][n] > 0)
return true;
else
return false;
}
int main()
{
int n, m, c;
cin >> n >> m >> c;
init(m);
if (judge(n, m, c))
cout << 2 * n - 2 << endl;
else
cout << "No" << endl;
}
评测结果:
补充:
这道题目相比于第十届蓝桥杯B组的第五题:迷宫问题,简单一些,只需考虑最后位置时的血量,不用关心中间路程它是怎么走的,不用给出相应的路径,下面给出迷宫问题:
转载于:蓝桥杯官网
后面我会给出迷宫问题的程序,感兴趣可以了解下。