2024年CCPC东北四省联赛

1.Problem J. Breakfast

输出39.20即可,保留两位小数,WA了一发...

#include<iostream>
using namespace std;

int main(){
    printf("%.2f", 0.6 * 32 + 20);
    return 0;
}

2.Problem A. Paper Watering

开方log(n)级别,次数少,不会超时。当时想法就是,如果开方不能整开开的数,那么他就能构成 (k - 1) + 1个数,如果能整开,平方就不会出现新数。

#include<iostream>
#include<cmath>
using namespace std;

int main(){
    std::ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    if(n == 1){
        cout << 1;
        return 0;
    }
    long long res = m + 1;
    int x = sqrt(n);
    m --;
    while(m != 0){
        if(x == 1){
            n = x;
            break;
        }
        if(x * x != n)
            res += m;
        res ++;
        n = x;
        x = sqrt(n);
        m --;
    }
    res ++;
    cout << res;
    return 0;
}

3.Problem D. nIM gAME

 前面都按照最优的拿,到最后只会有1,2,3个石子,  所以都会输...

#include<iostream>

using namespace std;

int main(){
    std::ios::sync_with_stdio(false);
    int n;
    cin >> n;
    while(n --){
        int x;
        cin >> x;
        cout << "lose" << endl;
    }
    
    return 0;
}

4.Problem E. Checksum

题意为pA + pB = D = B, 所以直接说 pA + pB = B就完全ok,说了一大堆... pA = B - pB,由于pA已知,B最的个数为2^20 - 1, B - pB 单调递增,预处理出来2^20 的 B - pB,二分查找。输出k位

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;

int p[2097200];
int pa[2097200];
int res[30];

int main(){
    // 20 * 1e6;
    std::ios::sync_with_stdio(false);
    for(int i = 1; i <= 1048576; i ++){
        int t = i;
        while(t){
            if(t & 1)
                p[i] ++;
            t = t >> 1;
        }
        pa[i] = i - p[i];
    }
    int T;
    cin >> T;
    for(int i = 0; i < T; i ++){
        int n, k;
        string s;
        cin >> n >> k;
        cin >> s;
        memset(res, 0, sizeof(res));
        // 统计 1 的个数
        int cnt = 0;
        for(int j = 0; j < n; j ++)
            if(s[j] == '1')
                cnt ++;
        int high = 1; // 多能表示多少 k最小为1
        for(int j = 0; j < k; j ++)
            high = high << 1;
        bool f1 = true;
        int f = lower_bound(pa + 1, pa + 1048577, cnt) - pa; // 找到 f 返回下标, 如果找不到 返回2097152
        if(f >= high || p[f] != cnt)
            f1 = false;
        if(f1){
            cnt = 1;
            while(f){ // 从后往前倒序输出
                res[cnt] = f % 2;
                cnt ++;
                f = f / 2;
            }
            for(int j = k; j >= 1; j --)
                cout << res[j];
            cout << endl;
        } else
            cout << "None" << endl;
    }
    return 0;
}

5.Problem L. Bracket Generation

这题当时队友想用dfs记忆化搜索,但觉得空间占用巨大,代码量巨大,同时伴随超时风险,就懒得写了,换个思路就简单了很多,对于每一个操作2的可能有操作2出现之后的操作都可以算作一种可能,而1操作只有一种可能,所以总可能数就是每一个2操作可能的乘积。我输入处理我能看懂的...

#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;

long long int mod = 998244353;

int main(){
    string s;
    cin >> s;
    int len = s.size();
    int cnt = 0;
    string tmp = "";
    for(int i = 0; i < len; i ++){
        if(i + 1 < len && s[i] == '(' && s[i + 1] == ')'){
            tmp += '1';
            i ++;
        }
        else if(s[i] == ')'){
            cnt ++;
            tmp += '2';
        }
    }
    // 分为1操作和2操作,对于每个2操作的可都都可以是 大于等于2操作出现的之后的每一种肯能,总共由 x个2 操作,
    // 他的总共可能性就是每个可能性的乘积
    long long res = 1;
    len = tmp.size();
    for(int i = len - 1; i >= 0; i ++){
        if(tmp[i] == '2')
            res = res * (len - i) % mod;
    }
    cout << res;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值