2021个人训练赛第11场

问题 G: 展示玩具

在这里插入图片描述
在这里插入图片描述
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

int a[5005];
int main() {
    int n, k;
    cin >> n >> k; //总数,最大差值
    for(int i = 1; i <= n; i ++) cin >> a[i];
    sort(a + 1, a + 1 + n);
    int res = 0;
    for(int i = 1; i <= n; i ++) {
        int p = upper_bound(a + 1, a + 1 + n, a[i] + k) - (a + 1);
        res = max(res, p - i + 1);
    }
    return cout << res, 0;
}

问题 H: ok 字符串

在这里插入图片描述
在这里插入图片描述
答案:

int main() {
    int n, k;
    cin >> n >> k; //字符串总长度,可以被修改的字符数
    string s;
    cin >> s;
    int a[26];
    memset(a, 0, sizeof(a));
    int res = 0, maxx = 0;
    for (int i = 0, j = 0; i < s.size(); i++)
    {
        int x = s[i] - 'a';
        a[x]++;
        maxx = max(maxx, a[x]); //出现最多的字符出现了多少次
        if (i - j + 1 - maxx > k)
        {
            a[s[j] - 'a']--;
            j++;
        }
        res = max(res, i - j + 1);
    }
    cout << res << endl;
    return 0;
}

测试代码,用于观察中间结果:

int main() {
    int n, k;
    cin >> n >> k; //字符串总长度,可以被修改的字符数
    string s;
    cin >> s;
    int a[26];
    memset(a, 0, sizeof(a));
    int res = 0, maxx = 0;
    for (int i = 0, j = 0; i < s.size(); i++)
    {
        int x = s[i] - 'a';
        cout << "\ntext " << "x=" << x << " j=" << j << " ";//
        a[x]++;
        cout << "A[x]=" << a[x] << " ";//
        maxx = max(maxx, a[x]); //出现最多的字符出现了多少次
        cout << "maxx=" << maxx << " ";//
        if (i - j + 1 - maxx > k)
        {
            cout << "[YYY]" << "i-j+1=" << i - j + 1 << " ";
            a[s[j] - 'a']--;
            cout << "j=" << j << " " << "j+1=" << j + 1 << " ";//
            j++;
        }
        res = max(res, i - j + 1);
        cout << "res=" << res << endl;//
    }
    cout << res << endl;
    return 0;
}

问题 I: 圣诞树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

const int maxn = 5100;

struct node {
    ll b, p;
} a[maxn], b[maxn]; //人民币,美金

bool cmp(node a, node b) {
    return a.b > b.b;
}

int main()
{
    ll n, c, d;
    cin >> n >> c >> d; //圣诞树总数,人民币,美金
    ll cnta = 0, cntb = 0;
    for (int i = 1; i <= n; i++) {
        char op[2];
        ll bb, p;
        cin >> bb >> p >> op;
        if (op[0] == 'C') a[++cnta] = {bb, p};
        else b[++cntb] = {bb, p};
    }
    ll res = 0;
    for (int i = 1; i <= cnta; i++) { //人民币买,两颗,最漂亮
        for (int j = i + 1; j <= cnta; j++) {
            if (a[i].p + a[j].p <= c) res = max(res, a[i].b + a[j].b);
        }
    }
    for (int i = 1; i <= cntb; i++) { //美元买,两颗,最漂亮
        for (int j = i + 1; j <= cntb; j++) {
            if (b[i].p + b[j].p <= d) res = max(res, b[i].b + b[j].b);
        }        
    }
    for (int i = 1; i <= cnta; i++) { //人民币买一棵,美元买一棵,最漂亮
        for (int j = 1; j <= cntb; j++) {
            if (a[i].p <= c && b[j].p <= d) res = max(res, a[i].b + b[j].b);
        }
    }
    cout << res << endl; //结果就是最最漂亮的
    return 0;
}

问题 K: 促销骰子

在这里插入图片描述
在这里插入图片描述
code:

int a[5005];

int main()
{
    int cnt = 1; //扔骰子次数
    while (1) {
        cin >> a[cnt];
        if (a[cnt] != 6 || cnt == 3) break; //不是6或掷满三次,停止
        cnt ++;
    }
    //找6
    if (cnt == 1) puts("0"); //扔第一次就不是6,仅扔了一次而已
    else if (cnt == 2) puts("10");//扔第二次是6
    else if (cnt == 3) { //扔了三次,前两次都是6,看第三次...
        if (a[3] == 6) puts("1000");
        else puts("100");
    }
    return 0;
}

问题 A: God Sequence

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
翻译:
如果b>=a,那么先输出长度为b的-1,-2,-3…
然后输出长度为a-1的1,2,3…,最后一个数让序列和为0即可

如果a>=b,那么先输出长度为a的1,2,3…
然后输出长度为b-1的-1,-2,-3…,最后一个数让序列和为0即可.

code:

int main()
{
    int a, b;
    cin >> a >> b;
    if (b >= a) {
        int sum = 0;
        for (int i = 1; i <= b; i++) {
            cout << -i << ' ';
            sum += -i;
        }
        for (int i = 1; i <= a - 1; i++) {
            cout << i << ' ';
            sum += i;
        }
        cout << -sum << endl;
    } else {
        int sum = 0;
        for (int i = 1; i <= a; i++) {
            cout << i << ' ';
            sum += i;
        }
        for (int i = 1; i <= b - 1; i++) {
            cout << -i << ' ';
            sum -= i;
        }
        cout << -sum << endl;
    }
    return 0;
}

问题 B: ARC Wrecker

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
翻译:
对于题目给定的一个数组,取出一个数,把比该数大的数都进行减一,求最后数组所有可能出现的额情况
思路:对数组排序
a[n-1]!=a[n],那么a[n]可以不变,也可以最多减到a[n-1],因此方案数为(a[n]-a[n-1]+1).
当a[n]减到a[n-1]时,之后的操作和a[n-1]同步了,可以看作合并了,直接不管

ll a[2000005];
int main()
{
    ll n;
    cin >> n;
    for (ll i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] == a[i - 1]) n --, i --;
    }
    sort(a + 1, a + 1 + n);
    ll lst = 1;
    a[0] = 0;
    for (ll i = n; i >= 1; i--) {
        lst = (lst * (a[i] - a[i - 1] + 1)) % 1000000007;
    }
    cout << lst << endl;
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值