一补提交卡一

题目大意
蒜头君给自己定了一个宏伟的目标:连续 100 天每天坚持在计蒜客题库提交一个程序。100 天过去了,蒜头君查看自己的提交记录发现有 N 天因为贪玩忘记提交了。于是蒜头君软磨硬泡、强忍着花椰菜鄙视的眼神从花椰菜那里要来 MM 张 “补提交卡”。每张 “补提交卡” 都可以补回一天的提交,将原本没有提交程序的一天变成有提交程序的一天。蒜头君想知道通过利用这 MM 张补提交卡,可以使自己的 “最长连续提交天数” 最多变成多少天。

输入格式
第一行是一个整数 T(1≤T≤10),代表测试数据的组数。

每个测试数据第一行是 2个整数 N和 M(0≤N,M≤100)。

第二行包含 N 个整数 a_1, a_2, … a_N(1≤a 1 <a 2<…<a N≤100)
表示第 a_1, a_2, … a_Na天蒜头君没有提交程序。

输出格式
对于每组数据,输出通过使用补提交卡蒜头君的最长连续提交天数最多变成多少。
输出时每行末尾的多余空格,不影响答案正确性

样例输入
3
5 1
34 77 82 83 84
5 2
10 30 55 56 90
5 10
10 30 55 56 90
样例输出

76
59
100

#include <iostream>
using namespace std;

const int max_n = 111;  // 定义最大的连续打开天数
int T;  // 定义测试数据的组数。
int n,m;  // 定义提交卡的数量m,n为未打卡的天数。
int num_max;  // 打卡的最长连续天数。
int num[max_n];  // 此为未打卡的天数。

int main() {

    cin >> T;
    while (T--){
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) {
            cin >> num[i];   //  初始化此数组。
        }
        for (int i = 1; i <= n; ++i) {
            int temp_m = m, temp_i = i; // 分别记录m,n(temp_i为第一次用提交卡那天。)
            while (temp_i <= n && temp_m > 0){
                temp_i++;
                temp_m--;
            }
            // while外的表示temp_i > n的情况。
            //表示当前使用提交卡的天数不是第一未打卡的天数,
            //此时连续的天数为100减去当前补提交卡的前一个未提交卡的天数。
            //或者是最后一次使用不提交卡的天数减去第一次使用提交卡的前一个未提交卡的天数。
            if (temp_i > n){
                num_max = max(num_max ,100 - num[i - 1] );
            }
            num_max = max(num_max ,(num[temp_i] - num[i - 1] - 1));

        }

        // 此情况是提交卡书数大于未打卡天数 。
        if (m >= n){
            num_max = 100;
        }

        // 此情况为没有提交卡。
        if (m == 0){
            for (int j = 1; j <= n; ++j) {
                num_max = max(num_max,(num[j] - num[j - 1] - 1));
            }
            num_max = max(num_max, 100 - num[n]);
        }
        cout << num_max << endl;
        num_max = 0;  // 多组数据测试,每组数据测试晚会,最大连续天数归零。
    }
    return 0;
}

枚举算法

设计步骤:

确定枚举对象(即问题解的表达形式,一般需要用若干参数来描述)
逐一列举可能(根据枚举对象的参数构造循环,一一列举其表达式的每一种取值情况)
逐一验证可能解( 根据问题解的要求,验证枚举对象表达式的每一个取值,如果满足条件,则采纳它,否则抛弃之。)
这里注意:①对象不能重复,不能遗漏;

              ② 每个参数要相互独立,这个时候算法才能简洁;每个参数的取值范围要搞清楚,尽可能小。

实际例子
在这里插入图片描述

解答

确定对象:对象就是解的表达式,用一个参数x表示;x的范围是(0~9)
逐一列举对象:用 x 确定的循环来一一列举可能的解
逐一验证可能的解,只有满足验证条件才能确定 x 的取值。
在这里插入图片描述
解答:

确定对象:这个可能的对象是有两个参数组成的,i,j ( i 的范围是[1-9] , j 的范围是[0–9] )
逐一列举循环:由于这里有两个参数,那必定要用到两层循环,一个以 i ,一个以 j。
逐一验证这些枚举的个体,满足条件的才可以取值。
在这里插入图片描述
当这里的三个数字都看不见的时候:

解答:

问题对象,这三个参数,其实可以看成是一个参数;x 取值100~999;这样参数减少了,代码易读;
逐一枚举,利用 x 的取值范围构成循环;但是这里三个参数看成是一个参数并没有减少复杂度
逐一进行验证,取满足条件的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值