Codeforces Round 970 (Div. 3)

A:

题目:

输入输出:

Input
5
0 1
0 3
2 0
2 3
3 1

Output
NO
NO
YES
YES
NO

思路:

先考虑2的个数,如果是偶数个,再看1的个数,如果是偶数个就是YES,否则是NO。如果2的个数是奇数个,就先让(b-1)个2自己消掉。最后剩下一个2,让1去消除。

代码:

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

void solve()
{
	int a,b;
	cin>>a>>b;
	b=b%2;
	
	if(b==0){
		if(a%2==0){
			cout<<"YES\n";
		}
		else{
			cout<<"NO\n";
		}
	}
	else{
		if(a%2!=0){
			cout<<"NO\n";
		}
		else{
			if(a>=2){
				cout<<"YES\n";
			}
			else{
				cout<<"NO\n";
			}
		}
	}
}
signed main()
{
	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

B:

题目:

输入输出:

Input
5
2
11
4
1111
9
111101111
9
111111111
12
111110011111

Output
No
Yes
Yes
No
No

思路:

先考虑n是否是一个数的平方,如果不是就是NO,否则继续比较,考虑到一个满足的矩阵必须是除了第一行和最后一行全是1以外,中间是1+(len-2)个0+1的形式。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;
string s;
void solve()
{
	cin>>n;
	cin>>s;
	
	if((int)sqrt(n)*sqrt(n)!=n){
		cout<<"NO\n";
	}
	else
	{
		int len=(int)sqrt(n);
		bool flag=true;
		vector<string>ans;
		for(int i=0;i<n;i+=len)
		{
			string ch=s.substr(i,len);
			ans.push_back(ch);
			//cout<<ch<<endl;
		}		
		
		string u,v;
		for(int i=0;i<len;i++) u.push_back('1');
		v.push_back('1');
		for(int i=0;i<len-2;i++) v.push_back('0');
		v.push_back('1');
		
		for(int i=0;i<ans.size();i++)
		{
			if(i==0&&ans[i]!=u){
				flag=false;
				break;
			}
			if(i==ans.size()-1&&ans[i]!=u){
				flag=false;
				break;
			}
			
			if(i>0&&i<ans.size()-1&&ans[i]!=v){
				flag=false;
				break;
			}
		}
		if(flag){
			cout<<"YES\n";
		}
		else{
			cout<<"NO\n";
		}
		
	}
	
}
signed main()
{
	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

C:

题目:

输入输出:

Input
5
1 2
1 5
2 2
10 20
1 1000000000

Output
2
3
1
5
44721

思路:

考虑到数组是严格单调递增,并且两个数的差值也是严格单调递增的,此时需要使得数组的长度最长,只要满足差值是1,2,3,4,5,即可。直接暴力即可;

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve()
{
	int l,r;
	cin>>l>>r;
	int u=1;
	int cnt=0;
	while(l<=r)
	{
		l+=u;
		u++;
		cnt++;
	}
	cout<<cnt<<"\n";
}
signed main()
{
	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

D:

题目:

输入输出:

Input
5
1
1
0
5
1 2 4 5 3
10101
5
5 4 1 3 2
10011
6
3 5 6 1 2 4
010000
6
1 2 3 4 5 6
100110

Output
1 
0 1 1 1 1 
2 2 2 2 2 
4 1 4 4 1 4 
0 1 1 0 0 1 

思路:

考虑哪几个点是在同一个集合里面的,全部找到,并看有几个是黑色的整数。将这一个集合内所有的数都赋值成这个数。关于利用联通块找到所有在同一个集合中的数参考求出单独连通块的数量_求单独连通区域个数-CSDN博客

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n;
int a[N];
string s;
map<int,bool>mp;
vector<int>ans[N];
map<int,int>mp1;
map<int,int>mp2;
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	
	cin>>s;
	s=" "+s;
	int id=1;
	for(int i=1;i<=n;i++)
	{
		
		if(mp[a[i]]==false)
		{
			mp[a[i]]=true;
		int st=a[i];
		int ne=a[st];
		ans[id].push_back(st);
		ans[id].push_back(ne);
		mp1[st]=id;
		mp1[ne]=id;
		mp[ne]=true;
		while(ne!=st)
		{
			ne=a[ne];
			mp[ne]=true;
			ans[id].push_back(ne);
			mp1[ne]=id;
		}
		sort(ans[id].begin(),ans[id].end());
		ans[id].erase(unique(ans[id].begin(),ans[id].end()),ans[id].end());
		
		for(int i=0;i<ans[id].size();i++){
			if(s[ans[id][i]]=='0'){
				mp2[id]++;
			}
		}
		id++;
	}
		
	}

	for(int i=1;i<=n;i++)
	{
		int id=mp1[i];
		cout<<mp2[id]<<" ";
	}
	for(int i=1;i<=id;i++){
		ans[i].clear();
	}
	cout<<"\n";
	mp.clear();
	mp1.clear();
	mp2.clear();

}
signed main()
{
	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

E:

题目:

输入输出:

Input
10
1
a
2
ca
3
aab
5
ababa
6
acdada
9
ejibmyyju
6
bbccbc
6
abacba
5
bcbca
5
dcbdb

Output
1
0
1
1
2
6
2
3
1
1

思路:

优先考虑n为偶数的情况,此时我们不会使用第一个操作,只会利用第二个操作,因为交替字符串最多只能有两种类型的字母出现,所以我们可以将字符串s的所有字符拿出来,暴力枚举所有的情况(最多是26*26),然后取出最少的情况即是答案。

再考虑到奇数的情况,必须利用操作1来删除一个字符,所以遍历字符串s的每一个位置,考虑到删除后的情况,m1代表奇数位置是字符j,m2代表偶数位置是字符j,最后是将其他位置的字符都改成字符j所要的操作步数(h-m1-m2);取出最小的操作步数+1,即是答案.

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n;
string s;
int res=1e18+10;
map<char,int>odd;
map<char,int>even;
int fun(char u,char v,string s)
{
	int cnt=0;
	for(int i=0;i<s.size();i++){
		if(i%2==0){
			if(s[i]!=u) cnt++; 	
		}
		else{
			if(s[i]!=v) cnt++;
		}
	}
	return cnt;
}
void solve()
{
	cin>>n;
	cin>>s;
	res=1e18+10;
	for(int i=0;i<s.size();i++){
		if(i%2) odd[s[i]]++;
		else even[s[i]]++;
	}
	
	if(n%2==0)
	{
		vector<char>ch;
		for(int i=0;i<n;i++){
			ch.push_back(s[i]);
		}
		sort(ch.begin(),ch.end());
		ch.erase(unique(ch.begin(),ch.end()),ch.end());
		
		
		for(int i=0;i<ch.size();i++){
			for(int j=0;j<ch.size();j++)
			{
				char u=ch[i];
				char v=ch[j];
				
				int ans=fun(u,v,s);
				res=min(res,ans);
			}
		}
		cout<<res<<"\n";
	}
	else
	{
		int h=n-1;
		for(int i=n-1;i>=0;i--)
		{
			if(i%2) odd[s[i]]--;
			else even[s[i]]--;
			
			int m1=0;
			int m2=0;
			
			for(int j='a';j<='z';j++){
				m1=max(m1,odd[j]);
				m2=max(m2,even[j]);
			}
			res=min(res,h-m1-m2);
			if(i%2){
				even[s[i]]++;
			}
			else{
				odd[s[i]]++;
			}
		}
		cout<<res+1<<"\n";
	}

	odd.clear();
	even.clear();

}
signed main()
{
	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

F:

题目:

输入输出:

Input
3
3
3 2 3
4
2 2 2 4
5
1 2 3 4 5

Output
7
6
500000012

思路:

由题意知道是求概率,p/q;由组合数学可以知道q=C[n][2]=n*(n-1)/2; 而p=a1*(a2+a3+..+an)=a1*(s[n]-s[i]);最后利用快速幂来求出p/q=p*qmi(q,mod-2,mod)%mod; 将答案用ans存起来,ans=(ans+mod)%mod;

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
const int N=2e5+10;
int n;
int a[N];
int s[N];
int p,q;

int qmi(int a,int k,int p)
{
	int res=1;
	while(k)
	{
		if(k&1) res=res*a%p;
		a=a*a%p;
		k>>=1;
	}
	return res;
}
void solve()
{
	cin>>n;
	
	for(int i=1;i<=n;i++){
		cin>>a[i];
		s[i]=(s[i-1]+a[i])%mod;
	}
	p=0;
	for(int i=1;i<=n;i++)
	{
		int sum=a[i]*(s[n]-s[i])%mod;
		p=(p+sum)%mod;
	}
	int q=n*(n-1)/2;
	q=q%mod;
	
	int ans=p*qmi(q,mod-2,mod)%mod;
	cout<<(ans+mod)%mod<<"\n";
	
}
signed main()
{
	cin.tie(0); cout.tie(0);
	ios::sync_with_stdio(false);
	int T;
	cin>>T;
	while(T--){
		solve();
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值