题目链接:

https://codeforces.com/problemset/problem/1561/C

题目大意:

t 组测试,有 n 个洞穴,每个洞穴有 k 个怪,每个怪有一个 armor 值,在洞穴中需要按照顺序打怪,你有一个 power 值,当 power 大于 怪的 armor 时,你可以打过这个怪,否则失败,每打一个怪,你的 power + 1,找到一个 最小 的 power 值,让你能够按照一定的顺序成功通过所有洞穴。

思路:

首先要知道 通过某个洞穴的最小 power

我们设要打的第一个洞穴的第一个怪的 armor 是 a(1) ,那么进入这个洞穴时的 power 是 a(1) + 1 时才能打过第一个怪,第二个怪的 armor 是 a(2) ,那么进入洞穴时 power 至少要为 a(2) + 1 - 1 时才能打过第二个怪, + 1 满足了 power > armor , - 1 是因为在这之前打了一个怪。我们要取两者中的 较大值
显然,我们可以递推得到打过这个洞穴中某个怪的 最小的进入洞穴时的 power 值 (有点绕) ,再取其中的最大值,就得到通过这个洞穴的最小的 power 。

接下来我们要去计算通过所有洞穴的最小的 power 值。

将通过每一个洞穴的最小 power 值(定义为 begin )及通过这个洞穴后增加的值 k 储存在结构体中,然后按照 begin 从小到大进行排序。

ps:我们设可以当前找过的所有洞穴的最小的 power 值为 ans ,通过前面所有洞穴增长的 power 为 len.

显然,会出现两种情况:
一、 ans + len < 当前洞穴的 begin ,那么 ans 的值就要更改为 begin - len。
二、 ans + len >= 当前洞穴的 begin ,那么 ans 不变。

即 ans = max( ans , begin - len );

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 100005;
struct power{
	int b, l;
}p[MAXN];
LL a;
int t, n, k, start, len;
bool cmp (power a,power b){
	return a.b < b.b;
}
int main(){
	cin >> t;
	while (t--){
		scanf("%d", &n);
		for (int i = 1; i <= n; i++){
			scanf("%d", &k);
			p[i].l = k;
			p[i].b = 0;
			for (int j = 1; j <= k; j++){
				scanf("%d", &a);
				p[i].b = p[i].b > a - j + 2 ? p[i].b : a - j + 2;
			}
		}
		sort(p + 1, p + n + 1, cmp);
		start = p[1].b;
		len = p[1].l;
		for (int i = 2; i <= n; i++){
			if (p[i].b > start + len) start = p[i].b - len;
			len += p[i].l;
		}
		cout << start << "\n";
	}
	return 0;
}
posted on 2021-08-30 21:07  Hamine  阅读(120)  评论(0编辑  收藏  举报