题目概况
链接: https://nanti.jisuanke.com/t/T1265
难度: 普及/提高-(计蒜客评级普及T3)
题目分析
简化题目: 100天内,有n天没提交,但有m张补提交卡可以用在m天上,用完它们,最长可以有多少天连续
涉及知识点: 枚举算法
解题思路:
我们可以通过枚举第一次用补提交卡的那一天,然后往后推m - 1
次,计算其连续天数,再取最大值。但通过多次WA 思考,我们得知m
可能为0
,m
也可以多于未提交的n
天数,所以逐情况考虑m
的情况:
1. m <= n
,按上述思路即可,但需要特别注意当枚举位置靠后时还往后推m
天可能越界越出n,需要做一下处理
2. m > n
,那不用算了,所有未提交都给补上,最长100天
3. m == 0
,在这种情况下,我们只能取第j
个未提交天和第j-1
个未提交天间的最长连续天
代码要点拆解
m <= n的情况
要点:
1.用mm
记录m
,用first
记录i
(第一次用补提交卡的那天)
2.用while
循环往后推,两个判断:first
不能超出n
,mm
必须大于0
3.如果first
超出了n
,那么就直接用100
减去当前第一个补提交天的前一个未提交天
4.没有特殊情况就直接用最后一次补提交天减去第一个补提交天再减1(这个自己可以举小例子推)
for (int i = 1; i <= n; i++) {
int mm = m, first = i; //记录
while (first <= n && mm > 0) {
first++;
mm--;
}
if (first > n) {
ans = max(ans, 100 - a[i - 1]);
}
ans = max(ans, (a[first] - a[i - 1] - 1));
}
m == 0以及m > n的情况
要点:见解题思路。就有一个要注意,我们的j
只循环到n
,那么还需要样100减去a[n]
if (m >= n) {
ans = 100;
}
if (m == 0) {
for (int j = 1; j <= n; j++) {
ans = max(ans, (a[j] - a[j - 1] - 1));
}
ans = max(ans, 100 - a[n]);
}
完整代码
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 105;
int T;
int n, m; //n天没提交,m张卡
int ans;
int a[MAXN];
int main() {
cin >> T;
while (T--) {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
int mm = m, first = i;
while (first <= n && mm > 0) {
first++;
mm--;
}
if (first > n) {
ans = max(ans, 100 - a[i - 1]);
}
ans = max(ans, (a[first] - a[i - 1] - 1));
}
if (m >= n) {
ans = 100;
}
if (m == 0) {
for (int j = 1; j <= n; j++) {
ans = max(ans, (a[j] - a[j - 1] - 1));
}
ans = max(ans, 100 - a[n]);
}
cout << ans << endl;
ans = 0; //多组数据记得清空ans变量
}
return 0;
}