Codeforces Round #732 (Div. 2)【A - D】

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

A. AquaMoon and Two Arrays

题意:给定一个两个长度为n的数字序列A,B,判断是否可以通过对A进行若干次以下操作得到B。
操作:任选两个下标1<=i!=j<=n,a[i]++,b[j]–

思路:直接判断需要加的次数和减的次数是否一致即可

#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
using namespace std;
const int N = 1e6 + 10;
inline void solve() {
    int n, ans = 0, k = 0;
    
    scanf("%lld", &n);
    vector<int> a(n), b(n), c, d;
    c.clear(); d.clear();
    for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
    for(int i = 0; i < n; i++) scanf("%lld", &b[i]);
    for(int i = 0; i < n; i++) {
        if(a[i] > b[i]) {
            for(int j = 1; j <= a[i] - b[i]; j++)
                c.push_back(i);
        }
        else if(a[i] < b[i]) {
            for(int j = 1; j <= b[i] - a[i]; j++)
                d.push_back(i);
        }
    }
    if(c.size() - d.size() != 0) cout << -1 << endl;
    else {
        cout << c.size() << endl;
        for(int i = 0; i < c.size(); i++) {
            cout << c[i] + 1 << " " << d[i] + 1 << endl;
        }
    }
    return ;
}
signed main() {
    int t; scanf("%lld", &t);
    while(t--) solve();
    return 0;
}

B. AquaMoon and Stolen String

题意:
给n(n为奇数)个长度为m的字符串,并按照以下规则打乱n-1个字符串,输出未被打乱的字符串

打乱规则:对于任意两个未被打乱规则的字符串s1,s2,选择一些位置i(1 <= i <= m),交换s1[i]和s2[i]的字母。

例如m=6,对于两个字符串"abcdef"和"xyzklm",选择位置2,3和6,把’b’换成’y’, ‘c’换成’z’, ‘f’换成’m’。得到的字符串将是"ayzdem"和"xbcklf"

思路:按照交换规则,对于n个字符串,字符串第i个位置的字符无论怎么变换,它出现的次数是不变的,经过变换以后,一定是等于0的,于是通过判断字符出现次数不为0时,即为未做改变的字符串的第i个位置字符。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, m;
string s[N], t[N];
inline void solve() {
    cin >> n >> m;
    for(int i = 1; i <= n; i++) cin >> s[i];
    for(int i = 1; i <= n - 1; i++) cin >> t[i];
    unordered_map<char, int> cnt;
    vector<char> ans;
    for(int i = 0; i < m; i++) {
        for(int j = 1; j <= n; j++) cnt[s[j][i]]++;
        for(int j = 1; j <= n - 1; j++) cnt[t[j][i]]--;
        for(int j = 1; j <= n; j++) {
            if(cnt[s[j][i]]) {
                ans.push_back(s[j][i]);
                cnt[s[j][i]] = 0; break;
            }
        }
    }
    for(int i = 0; i < ans.size(); i++) cout << ans[i]; cout << endl;
    return ;
}
signed main() {
    int t; cin >> t;
    while(t--) solve();
    
    return 0;
}

C. AquaMoon and Strange Sort

题意:给定n个数,可以进行任意次相邻数交换,目标序列是不递增序列,问对于每个数能否用偶数次操作使得它们回到目标位置上。

思路: 由于n个数要经过偶数次操作使它们回到目标位置,那么奇数位的元素必须回到奇数位,偶数位必须回到偶数位,那么可以通过判断原本在奇数位的元素在排完序以后是否也在奇数位即可。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
inline void solve() {
    int n; cin >> n;
    vector<int> x(n);
    for(int i = 0; i < n; i++) cin >> x[i];
    unordered_map<int, int> cnt;
    for(int i = 0; i < n; i++) {
        if(i & 1) cnt[x[i]]++;
        else cnt[x[i]]--;
    }
    sort(x.begin(), x.end());
    for(int i = 0; i < n; i++) {
        if(i & 1) cnt[x[i]]--;
        else cnt[x[i]]++;
    }
    for(int i = 0; i < n; i++)
        if(cnt[x[i]]) {
            cout << "No" << endl;
            return ;
        }
    cout << "Yes" << endl;
    return ;
}
signed main() {
    int t; cin >> t;
    while(t--) solve();
    return 0;
}

D. AquaMoon and Chess

题意:给一个由01组成的字符串s,对于每一个字符s[i] = ‘1’,有以下操作
①:i+2≤n并且s[i+1] = ‘1’,那么s[i +2]可以等于’1’
②:i - 2 >= 1并且s[i-1]=‘1’,那么s[i-2]可以等于’1’
请问字符串有多少种变化方式

思路:组合数规律,数成对的1的个数n,0的个数m,答案是C(n+m,n)

代码:

#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
using namespace std;
const int N = 1e6 + 10, mod = 998244353;
inline int qpow(int a, int b) {
	int res = 1;
	while (b)
	{
		if (b & 1) res = (res * a) % mod;
		a = a * a % mod, b >>= 1;
	}
	return res % mod;
}

inline int work(int n, int m) {
    int s = 1, c = 1;
    for (int i = 1; i <= m; i+=1)
        s = (s * i) %mod; //计算分母
    for (int i = n - m + 1; i <= n; i++) 
        c = (c * i) % mod; //计算分子
    return (c * qpow(s, mod - 2)) % mod; //求出值
}
inline void solve() {
    int n; cin >> n;
    int s1 = 0, s2 = 0;
    string s; cin >> s;
    for(int i = 0; i < s.size(); i++) {
        if(s[i] == '0') s1++;
        else if(s[i] == '1' && s[i + 1] == '1') {
            s2++; i++;
        }
    }
    cout << work(s1 + s2, s1) << endl;
    return ;
}
signed main() {
    int t; scanf("%lld", &t);
    while(t--) solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顶白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值