标签(空格分隔): hihocoder
题目:#1051:补提交卡
小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 90Sample Output
76
59
100
一开始做这道题的时候,我的想法是找出每个间隔的天数,相当于在补上0和100后,计算相邻两个数的差,本身用1代表。这样,比如输入[34 77 82 83 84]就变为了[0 34 77 82 83 84 100],间隔数组为[33 1 42 1 4 1 1 1 16]。然后对于有多少个M,就表示可以填多少个1,可以推断出,当可以“填”的1是连续的时候,可以获得的连续天数最大。但是这样做,情况很多,数据处理起来计算也很麻烦。对于间隔数组计算最大连续天数时,如果用链表,进行下一次连续值计算时要回溯或者保留1的位置信息,使用队列似乎也方便一些。但是对于[1 3 5 7…]这样的输入有很…这样的输入的间隔数组为[1 1 1 1 1 1 1…]。前面的一切假设就都没了…
人真傻,想得这么复杂,描述得也乱七八糟…
痛定思痛,重新思考,其实可以把输入添头加尾,形成新的数组[0 34 77 82 83 84 100],通过这个数组可以直接求出最大的连续数,就是相邻间差最大的数。而M次机会填充相当于可以“抹去”原始输入中的M个数。理论上有
CMN
种情况,但是输入是排序的,因此连续填充情况下才有可能出现最大值,因此有效情况是N-M+1种情况。链表或数组的改动容易出错,特别是循环中想删除某些值。因此正向添加,两个指示坐标分别是i和i+M-1。删除值后的输入添头加尾,然后求相差最大的相邻数就行了。
多审题,在下笔…就是脑子太笨,审不清楚,也只好先写了。
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
private static int getMaxCon(ArrayList<Integer> listnums,
int M)
{
int max = 0;
for (int i = 0; i < listnums.size() - 1; i++) {
if (listnums.get(i+1) - listnums.get(i) > max) {
max = listnums.get(i+1) - listnums.get(i) - 1;
}
}
return max;
}
public static void main(String[] args) {
Scanner sin = new Scanner(System.in);
int numlines = Integer.valueOf(sin.nextInt());
sin.nextLine();
while(numlines-- != 0){
String P = sin.nextLine();
int N = Integer.valueOf(P.split("\\s")[0]);
int M = Integer.valueOf(P.split("\\s")[1]);
int[] numsDefault = new int[N+1];
String T = sin.nextLine();
String[] tmpNums = T.split("\\s");
for (int i = 0; i < N; i++) {
numsDefault[i] = Integer.valueOf(tmpNums[i]);
}
numsDefault[N] = 100;
if ( M>= N) {
System.out.println(100);
} else {
int max = 0;
for (int i = 0; i < N - M + 1; i++) {
ArrayList<Integer> listNum = new ArrayList<Integer>();
listNum.add(0);
for (int j = 0; j < N; j++) {
if (j < i || j > i+M-1) {
listNum.add(numsDefault[j]);
}
}
listNum.add(100);
if (getMaxCon(listNum, M) > max) {
max = getMaxCon(listNum, M);
}
}
System.out.println(max);
}
}
}
}