2024牛客暑期多校训练营6

H:

H-Genshin Impact's Fault_2024牛客暑期多校训练营6 (nowcoder.com)

题意:

在《原神》游戏中,许愿是一种尝试获得特定角色的行为。

在这个问题中,许愿有四种可能的结果:

  1. 3星武器,
  2. 4星武器/角色,
  3. 5星非促销武器/角色,
  4. 5星促销武器/角色。这里,我们不区分武器和角色,并分别用3、4、5和U来表示每个结果。

制订许愿的一些规则:

  1. 每连续10个许愿中不会只包含3星武器。
  2. 每连续90个许愿中必须至少包含一个5星武器/角色,不论是否是促销的。
  3. 每两个相邻的5星武器/角色之间必须至少有一个是促销的。这里,如果两个5星武器/角色之间所有的许愿都不是5星武器/角色,则称这两个5星为相邻。

现在给你一个许愿列表。判断它是否符合上述规则。

输入描述: 第一行包含一个整数T(1≤T≤10^5),代表测试用例的数量。

对于每个测试用例,单独一行包含一个字符串S(1≤|S|≤10^6),字符串仅包含3、4、5和U。

保证∑|S|≤10^6。

输出描述: 对于每个测试用例,如果符合上述规则,输出"valid",否则输出"invalid"。

解析:

这道题目的注意点就是对于规则二来说,90个许愿可以是从0~89,也可以是1~90,2~91。因此我们可以用滑动窗口来解决。规则三的巧妙的地方就是在原本字符串中提取5和U,构造成一个新的字符串,查找是否存在55即可。

#include<bits/stdc++.h>
using namespace std;

void solve(string s) {
    bool invalid = false;
    
    // 检查连续的10个3星
    int p = s.find("3333333333");
    if (p != -1) invalid = true;
    
    // 每90个许愿至少有一个5星或促销U
    int count5U = 0, start = 0;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == 'U' || s[i] == '5') {
            count5U++;
        }
        // 完成90个字符的检查
        if (i - start + 1 == 90) {
            if (count5U == 0) {
                invalid = true;
                break;
            }
            // 移动窗口
            if (s[start] == 'U' || s[start] == '5') {
                count5U--;
            }
            start++;
        }
    }

    // 检查连续两个5星之间必须有促销U
    string ss;
    for (char ch : s) {
        if (ch == 'U' || ch == '5') ss += ch;
    }
    if (ss.find("55") != -1) invalid = true;
    
    if (invalid) cout << "invalid" << '\n';
    else cout << "valid" << '\n';
}

int main() {
    int t; cin >> t;
    while (t--) {
        string s; cin >> s;
        solve(s);
    }
    return 0;
}

B:

B-Cake 2_2024牛客暑期多校训练营6 (nowcoder.com)

题目大意:

对于一个给定边数为 n 的规则多边形,通过连接顶点 i 和 (i+k)mod n 的线段来切割蛋糕,我们需要确定切割后的区域数。

解析:

画几个图即可

例1:n = 8, k = 4,共有8个区域

例2: n = 8, k = 5 ,共有25个区域

 

例3:n = 7, k = 3,共有22个区域。

 从例1我们可以知道,当n = 2 * k,区域个数就为n

从例3 我们可以知道,当n != 2 * k,区域个数可能为n * k + 1

从例2我们可知,n * k + 1不满足区域个数,区域个数为n * (n - k) + 1,此时 n - k < k;

综上所述,当n = 2 * k,区域个数就为n。否则就为 n * min (n - k, k) + 1

本题需要开long long。

#include<bits/stdc++.h>

using namespace std;
using ll = long long;
int main() {
    ll n, k;
    cin >> n >> k;
    ll result = 0;
    if(2*k == n) result = n;
    else result = n * min(k,n-k) + 1;
    cout << result << endl;
    
    return 0;
}

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值