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

A题:AquaMoon and Two Arrays
题意:给定n和数组an,bn。操作为选择两个下标使得ai–,aj++,使an和bn数组相同。
数据范围:多组输入t<100,n<100,ai,bi<100
样例解释
输入:
4
4
1 2 3 4
3 1 2 4
2
1 3
2 1
1
0
0
5
4 3 2 1 0
0 1 2 3 4
输出:
2
2 1
3 1
-1
0
6
1 4
1 4
1 5
1 5
2 5
2 5
第一组:
i=2, j=1: [1,2,3,4]→[2,1,3,4];
i=3, j=1: [2,1,3,4]→[3,1,2,4];
思路:数据范围小,直接模拟遍历,查找符合的下标记录并修改。
分类:暴力
通过代码:

#include<bits/stdc++.h>
using namespace std;
int a[105],b[105];
int main() {
	int t;
	cin>>t;
	while(t--) {
		int n;
		cin>>n;
		vector<pair<int,int> >v;//存入需要交换的i,j 
		for(int i=1; i<=n; i++)cin>>a[i];
		for(int i=1; i<=n; i++)cin>>b[i];
		for(int i=1; i<=n-1; i++) {//暴力遍历n2 
			for(int j=i+1; j<=n; j++) {
				if(a[i]>b[i]&&a[j]<b[j]) {//如果i位大并且j位小 
					a[i]--;//修改a[i],a[j]值 
					a[j]++;
					v.push_back({i,j});//存入i,j 
					j--;//注意回退 
				} else if(a[i]<b[i]&&a[j]>b[j]) {//如果i位小并且j位大同理 
					a[i]++;
					a[j]--;
					v.push_back({j,i});
					j--;
				}
			}
		}
		int flag=1;
		for(int i=1;i<=n;i++)if(a[i]!=b[i])flag=0;//判断最后是否相同 
		if(flag) {
			cout<<v.size()<<endl;
			for(auto x:v)cout<<x.first<<" "<<x.second<<endl;
		} else {
			cout<<-1<<endl;
		}
	}
	return 0;
}

B题:AquaMoon and Stolen String
题意:给定字符串数量n和长度m,给定n行和n-1行,通过n行中每一位的任意交换,形成和另外n-1行相同的字符串,输出剩下的字符串
数据范围:多组输入t<100,n,m<1e5
数据范围:多组输入t<1e4,|s|<26
样例解释
输入:
3
3 5
aaaaa
bbbbb
ccccc
aaaaa
bbbbb
3 4
aaaa
bbbb
cccc
aabb
bbaa
5 6
abcdef
uuuuuu
kekeke
ekekek
xyzklm
xbcklf
eueueu
ayzdem
ukukuk
输出:
ccccc
cccc
kekeke
第一组:显然剩余了第三行
思路:统计每一位的字符串个数,将n行和n-1行相减,剩下的字符为当前位剩余字符。
分类:计数
通过代码:

#include<bits/stdc++.h>
using namespace std;
string s1[100005],s2[100005];
int cnt[200];
int main() {
	int t;
	cin>>t;
	while(t--) {
		int n,m;
		vector<char>v;
		cin>>n>>m;
		for(int i=0; i<n; i++) cin >> s1[i];
		for(int i=0; i<n-1; i++) cin >> s2[i];
		for(int i=0; i<m; i++) {//每一位 
			memset(cnt,0,sizeof cnt);
			for(int j=0; j<n; j++)cnt[s1[j][i]]++;//统计增加的字符 
			for(int j=0; j<n-1; j++)cnt[s2[j][i]]--;//统计减少的字符 
			for(int j='a'; j<='z'; j++) {
				if(cnt[j]==1)v.push_back(j);//差值为1的为剩余字符 
			}
		}
		for(auto x:v)cout<<(char)x;
		cout<<endl;
	}
	return 0;
}

C题:AquaMoon and Strange Sort
题意:给定n和数组an,初始所有元素朝右,与相邻元素交换后改变方向,求最终能否升序且方向均朝右。
数据范围:多组输入t<50,n<1e5,ai<1e5
样例解释
输入:
3
4
4 3 2 5
4
3 3 2 2
5
1 2 3 5 4
输出:
YES
YES
NO
第一组:
交换1和2. [3,4,2,5]. 方向: 左左右右
交换2和3. [3,2,4,5]. 方向: 左左右右
交换1和2. [2,3,4,5]. 方向: 右右右右
思路:如果要使每个元素最终都朝右,说明交换次数%2=0,即奇数位和奇数位交换,偶数位和偶数位交换,同时又要满足升序条件。只需要把奇数位和偶数位独立排序一次,再将原数组排序一次,即可判断答案
分类:奇偶+排序
通过代码:

#include<bits/stdc++.h>
using namespace std;
int main() {
	int t;
	cin>>t;
	while(t--) {
		int n,x;
		cin>>n;
		vector<int>a,b,c;
		for(int i=0; i<n; i++) {
			cin>>x;
			a.push_back(x);
		}
		for(int i=0; i<n; i++) {
			if(i%2==1)b.push_back(a[i]);
			else c.push_back(a[i]);
		}
		sort(a.begin(),a.end());
		sort(b.begin(),b.end());
		sort(c.begin(),c.end());
		int flag=1;
		for(int i=0; i<n; i++) {
			if(i%2==1) {
				if(a[i]!=b[i/2])flag=0;
			} else {
				if(a[i]!=c[i/2])flag=0;
			}
		}
		if(flag)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

D题:AquaMoon and Chess
题意:给定字符串长度n和一个01字符串,可以完成操作:
如果s[i]==1&&s[i+1]==1&&s[i+2]==0则s[i]=0,s[i+2]=1;
如果s[i]==1&&s[i-1]==1&&s[i-2]==0则s[i]=0,s[i-2]=1;
请问最终有多少种不同结果,模998244353
数据范围:多组输入t<1e4,n<1e5
样例
样例输入:
6
4
0110
6
011011
5
01010
20
10001111110110111000
20
00110110100110111101
20
11101111011000100010
样例输出:
3
6
1
1287
1287
715
思路:打表找规律。如果只有0,显然不会变化;如果只有孤立的1,显然也不会有变化;如果有两个连续的1,可以跑遍整个数组;
如果此时出现孤立的1,遇到时会被传递,不具有贡献;如果有三个连续的1,仅能看成(1+1)*两个连续的1,无法造成额外的贡献;
如果有四个连续的1,可以看作(1+1+1)*两个连续的1……简化了连续1问题以后,发现状态数和这个11所放的位置有关。
所有的11都可以放到0的位置上,即变成了有个数(0)和个数(11)之和个位置,来放置个数(11),求多少个方案数。
即组合数问题。
分类:思维,排列组合
通过代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=998244353;
ll qmi(ll a, ll k)//快速幂模板
{
    int res = 1;
    while (k)
    {
        if (k & 1) res = (ll)res * a % mod;
        a = (ll)a * a % mod;
        k >>= 1;
    }
    return res;
}
ll C(ll a, ll b)//通过定理求组合数C(a, b)
{
    ll res = 1;
    for (int i = 1, j = a; i <= b; i ++, j -- )
    {
        res = (ll)res * j % mod;
        res = (ll)res * qmi(i, mod - 2) % mod;
    }
    return res;
}
ll lucas(ll a, ll b)
{
    if (a < mod && b < mod) return C(a, b);
    return (ll)C(a % mod, b % mod)*lucas(a / mod, b / mod) % mod;
}
int main() {
	ll t;
	cin>>t;
	while(t--) {
		ll n;
		string s;
		cin>>n>>s;
		ll cnt0=0,cnt1=0;
		for(int i=0; i<s.size(); i++) {
			if(s[i]=='0')cnt0++;//统计0的个数 
		}
		for(int i=0; i<s.size(); i++) {
			if(s[i]=='1') {
				int pos=i;
				while(s[pos]=='1'){
					pos++;
				}
				cnt1+=(pos-i)/2;//统计多少个连续的11个数 
				i=pos;
			}
		}
		cout<<lucas(cnt0+cnt1,cnt1)<<endl;//组合数问题 
	}
	return 0;
}

E题:AquaMoon and Permutations
分类:???

F题:AquaMoon and Wrong Coordinate
分类:???

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值