1617: 补提交 好家伙,今天的第二弹来了......

1617: 补提交

Description

TOM给自己定了一个宏伟的目标:连续100天每天坚持在zcmu上提交一个程序。100天过去了,tom查看自己的提交记录发现有N天因为贪玩忘记提交了。于是TOM要来M张"补提交卡"。每张"补提交卡"都可以补回一天的提交,将原本没有提交程序的一天变成有提交程序的一天。tom想知道通过利用这M张补提交卡,可以使自己的"最长连续提交天数"最多变成多少天。

Input

第一行是一个整数T(1 <= T <= 10),代表测试数据的组数。

每个测试数据第一行是2个整数N和M(0 <= N, M <= 100)。第二行包含N个整数,表示第a1, a2, … aN天TOM没有提交程序。ai<=100

Output

对于每组数据,输出通过使用补提交卡TOM的最长连续提交天数最多变成多少。

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

思路

题意告诉我们,先输入输入组的个数,再输入每一组的未提交的天数,再输入补题交卡的张数。
那么很显然,如果补提交卡的张数大于或等于漏提交的天数,那么则可以补完所有的天数,直接输出100即可。
如果补提交卡的张数小于未提交的天数,则要进行计算,看看补哪几天题,连起来更多。
我们可以想到,只有当补提交卡连续使用时才有可能达到最大,因为如果隔了未提交的一天进行使用,那么可能前面连着的变多了,后面连着的天数也变多了,但这绝不是能得出最大的方法,所以必须连续使用补题交卡。
用第二个案例来举例
5 2
10 30 55 56 90
有两张补题交卡,连续使用可以为补10 30、30 55、55 56、56 90
显然选55 56是最合适的选择
但如何算出补哪两个能得到最大呢?
我们可以通过让补掉的相邻两天相减再减去1
例如:
90-30-1=59;
因为90和30这两天是都没有提交的,所以在计算的时候要减掉一个1;
比如说一共三天只看了第二天这么一天,那么3-1之后还要减去一个1;
所以我们只要计算补掉的那两天的相邻未补两天的之间的差再减1就好;
然后再把最大的值赋给max输出即可;

细节

若取到的要补的天数个数是第一个或是最后一个,就会出现左边没有相邻的未提交的天数,或右边没有相邻的未提交的天数,于是,我们要在每组数据的最前端和最后端分别加上一个与最小的天数相邻的0,和与最大天数相邻的101进行辅助计算。
我们把输入的每组数据定义成数组的形式a[101],并把a[0]的值设为0,把a[m+1]设为101;
我们在遍历的时候只要遍历m+1-n次即可,因为相减的两个数之间间隔着我们所持有补提交卡的数量;

代码展示

#include<bits/stdc++.h>
using namespace std;
int main()
{
     
	int repeat,t,m,n,i,j,a[101]={
     0},max,x;
	while(scanf("%d",&repeat)!=EOF)
	{
     
	for(t=0;t<repeat;t++)
	{
     
		scanf("%d%d",&m,&n);
		for(i=1;i<=m;i++)
		{
     
			scanf("%d",&a[i]); 
		} 
		a[m+1]=101;
		if(n>=m)
		{
     
			printf("100\n");
			continue;
		} 
		if(n<m)
		{
     
			max=0;
			for(j=0;j<m+1-n;j++)
			{
     
				x=a[j+n+1]-a[j];
				if(x>max)
			{
     
				max=x;
			}
			}
			printf("%d\n",max-1);	
		}
	}	
	}
	return 0;
}

结尾

希望对大家有帮助!!!
有问题可在下面留言,谢谢…
哈哈,还是一样…
本人刚开始学没多久,并且心理承受能力不太行,如有错误或更好的方法请好好说,千万别骂我,拜托拜托

你可能感兴趣的:(c语言)