# hihocoder #1051 补提交卡

标签(空格分隔): 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 90

Sample 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);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值