小Ho给自己定了一个宏伟的目标:连续100天每天坚持在hihoCoder上提交一个程序。100天过去了,小Ho查看自己的提交记录发现有N天因为贪玩忘记提交了。于是小Ho软磨硬泡、强忍着小Hi鄙视的眼神从小Hi那里要来M张"补提交卡"。每张"补提交卡"都可以补回一天的提交,将原本没有提交程序的一天变成有提交程序的一天。小Ho想知道通过利用这M张补提交卡,可以使自己的"最长连续提交天数"最多变成多少天。
INPUT
第一行是一个整数T(1 <= T <= 10),代表测试数据的组数。
每个测试数据第一行是2个整数N和M(0 <= N, M <= 100)。第二行包含N个整数a1, a2, … aN(1 <= a1 < a2 < … < aN <= 100),表示第a1, a2, … aN天小Ho没有提交程序。
OUTPUT
对于每组数据,输出通过使用补提交卡小Ho的最长连续提交天数最多变成多少。
Sample Input
3
5 1
34 77 82 83 84
5 2
10 30 55 56 90
5 10
10 30 55 56 90
Sample Output
76
59
100
思路:肯定是将这些卡片连续用会达到更大的连续天数,所以我的做法就是从开始的空天开始连续补M个空天,补完之后记录下连续天数,然后再从第二个空天开始,再连续补M个空天,然后看哪个连续的天数最长就是答案。
当然这道题有些极端的例子,然后我在前面加了if条件,如果满足就直接输出然后继续循环。(这个也需要想想,不考虑肯定就错了)
当然具体怎么实现呢,还是要想一会,因为中间实现也比较乱吧,不是一下就能写对,我还是debug了很久,但是这道题还是比较基础吧,我一遍就过了耶,虽然也没什么好高兴的,但是好久没有尝试过一遍就过的心情了,弱……
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
int main()
{
int T;
int a[105];
scanf("%d",&T);
while(T--)
{
memset(a,false,sizeof(a));
int N,M;
int num;
scanf("%d%d",&N,&M);
for(int i=0; i<N; i++)
{
scanf("%d",&num);
a[num]=1;//这里我采用的是如果是空天就标记为1,如果不是空天就是0,方便后面判断
}
if(N==100&&M==0)//这里就是如果100天都是空天,然后补卡还没有,就直接输出0。但是这里要注意的是这两个条件N==100和M==0不能改变位置,这个与符号在计算机中判断是有点点小技巧的,和人脑的思维一样,如果前者为0,整个为0,不会再判断后者是否为0;如果前者不为0,才继续判断后者是否为0。所以这里如果把M放在前面的话,那10,0输出也是0,显然不正确。
{
printf("0\n");
continue;
}
if(M>=N||N==0)//这里就是如果卡片大于空天数,或者空天数为0那么就直接输出100,连续的天数是满天
{
printf("100\n");
continue;
}
int temp_begin=0;//这个是用来记录我们要补上的连续空天的第一个空天的,开始肯定从0开始
int max_=0;//这个是用来存最大连续天数的
int total=0;//这个是用来存 每个我们补齐完空天之后的连续天数-M的值
int sum;
for(int i=0; i<100; i++)
{
if(a[i]==1)
{
sum=M+1;//因为我们要判断的第一个空天到它前边的那个空天的区间也需要加进total,所以这里sum应该是M+1
total=0;//每个补齐工作前total赋为0
for(int j=i; j<100; j++)
{
if(a[j]==0)
continue;
if(sum)//直到M个空点的前后区间都判完为止
if(a[j]==1)
{
total+=j-temp_begin-1;//这里的话就自己画一下线段图就明白了
temp_begin=j;//换下一个空天
sum--;
}
}
max_=max(max_,total+M);
temp_begin=i;//这一步就是说要初始化下一个补齐工程的第一个空点
}
}
printf("%d\n",max_);
}
return 0;
}