2025牛客寒假算法基础集训营5

C.小L的位运算

因为交换a,b的代价一样,所以将a,b看作整体,分为00,01,10,11四种,两两相互之间都可以转化,如果最多的一种小于总数的一半,那么一定有一种方法可以将剩下的两两转化直至剩下不到两个,反之所有的都和最多的转化即可

#include <bits/stdc++.h>

#define lowbit(x) ((x)&(-x))
#define all(x) x.begin(),x.end()
#define int long long
using namespace std;
const int N = 1e3 + 10;
const int MOD = 1e9 + 7;

vector<int> cnt(4);

void solve() {
    int n, x, y;
    cin >> n >> x >> y;
    string a, b, c;
    cin >> a >> b >> c;
    int total = 0;
    for (int i = 0; i < n; i++) {
        int num_a = a[i] - '0';
        int num_b = b[i] - '0';
        int num_c = c[i] - '0';
        if ((num_a ^ num_b) != num_c) {
            cnt[num_a + num_b * 2]++;
            total++;
        }
    }
    sort(all(cnt));
    if (y < 2 * x) {
        int ans=0;
        if(cnt[3]>cnt[0]+cnt[1]+cnt[2]){
            int rev=cnt[3]-(cnt[0]+cnt[1]+cnt[2]);
            ans=(rev)*x+((total-rev)/2)*y;
        }else{
            int rev=total%2;
            ans=rev*x+(total-rev)/2*y;
        }
        cout << ans << '\n';
    } else {
        cout << total * x << '\n';
    }
}

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
//    cout << fixed << setprecision(15);
    int _ = 1;
//    cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

D.小L的字符串翻转

贡献由每段中是否有01分界点来决定,所以只要判断每段中是否同时存在01即可,最后答案就是分界数+1。

#include <bits/stdc++.h>  
  
#define lowbit(x) ((x)&(-x))  
#define all(x) x.begin(),x.end()  
#define int long long  
using namespace std;  
const int N = 1e3 + 10;  
const int MOD = 1e9 + 7;  
  
void solve() {  
    int n;  
    string s;  
    cin >> n >> s;  
    s = ' ' + s;  
    vector<int> pre_0(n + 1);  
    vector<int> pre_1(n + 1);  
    vector<int> ans(n + 1);  
    for (int i = 1; i <= n; i++) {  
        pre_0[i] = pre_0[i - 1];  
        pre_1[i] = pre_1[i - 1];  
        if (s[i] == '1') pre_1[i]++;  
        else pre_0[i]++;  
    }  
    for (int k = 1; k <= n; k++) {  
        for (int l = 1, r = k; l <= n; l += k, r += k) {  
            r = min(n, r);  
            if (pre_0[r] - pre_0[l - 1] != 0 && pre_1[r] - pre_1[l - 1] != 0) {  
                ans[k]++;  
            }  
        }  
    }  
    int res = 0;  
    for (int i = 1; i <= n; i++) {  
        res ^= (ans[i] + 1);  
//        cout << ans[i] + 1 << ' ';  
    }  
    cout << res << '\n';  
}  
  
signed main() {  
    cin.tie(0);  
    cout.tie(0);  
    ios::sync_with_stdio(0);  
//    cout << fixed << setprecision(15);  
    int _ = 1;  
//    cin >> _;  
    while (_--) {  
        solve();  
    }  
    return 0;  
}

L .小L的构造

相邻的数互质,相邻的奇数互质,所以连续三个数无法构造,连续六个数可构造两对,按此方法构造即可(方法不唯一)

#include <bits/stdc++.h>  
  
#define lowbit(x) ((x)&(-x))  
#define all(x) x.begin(),x.end()  
#define int long long  
using namespace std;  
const int N = 2e5 + 10;  
const int MOD = 1e9 + 7;  
  
  
void solve() {  
    int n;  
    cin >> n;  
    if (n <= 3) {  
        cout << 0 << '\n';  
        return;  
    }  
    int p = n / 3;  
    cout << p << '\n';  
    n = p * 3;  
    if (p == 1) {  
        cout << "1 2 4\n";  
        return;  
    }  
    if (p & 1) {  
        cout << "1 2 4\n3 9 5\n6 8 7\n";  
        for (int i = 10; i <= n; i += 6) {  
            cout << i << ' ' << i + 1 << ' ' << i + 4 << '\n';  
            cout << i + 2 << ' ' << i + 3 << ' ' << i + 5 << '\n';  
        }  
    } else {  
  
        for (int i = 1; i <= n; i += 6) {  
            cout << i << ' ' << i + 1 << ' ' << i + 3 << '\n';  
            cout << i + 2 << ' ' << i + 4 << ' ' << i + 5 << '\n';  
        }  
    }  
}  
  
signed main() {  
    cin.tie(0);  
    cout.tie(0);  
    ios::sync_with_stdio(0);  
//    cout << fixed << setprecision(15);  
    int _ = 1;  
    cin >> _;  
    while (_--) {  
        solve();  
    }  
    return 0;  
}
posted @   yoez123  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示