Codeforces Round 925 (Div. 3) A-F

链接:Dashboard - Codeforces Round 925 (Div. 3) - Codeforces

A. Recovering a Small String

题意:a到z表示1-26,给出一个数字,要求用三位字母组成的字符串表示,同时这三位字母加起来等于这个数字,使得字符串字典序最小。

思路:后面的字符越大越好

代码:

#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=1e5+7;


void solve(){
	int n;
	cin>>n;
	if(n<=28){
		cout<<"aa"<<(char)(n-2-1+'a')<<endl;
		return;
	}
	else if(n<=53){
		cout<<"a"<<(char)(n-27-1+'a')<<"z"<<endl;
		return;
	}
	else{
		cout<<(char)(n-52-1+'a')<<"zz"<<endl;
		return;
	}
} 

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

B. Make Equal

题意:给出n个数字,前面的数字可以匀给后面的,请问是否可以让所有数字一样。

思路:从前往后累积,只要能超过总和的平均就是合理的

代码:

#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=1e5+7;


void solve(){
	int n;
	cin>>n;
	vector<ll> a(n+2);
	ll sum=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
	}
	sum/=n;
	int x=0;
	for(int i=1;i<=n;i++){
		x+=a[i];
		if(x<sum*i){
			cout<<"NO"<<endl;
			return;
		}
	}
	cout<<"YES"<<endl;
} 

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

C. Make Equal Again

题意:对于长度为n的数组,选定一个区间将其中全部数字修改为指定的值,然后使得整个数组数字相等,求这个区间的最短长度。

思路:首先前后连续区间是对答案是有贡献的,当前后俩段相等区间的值相等时候,共同有贡献,否则就选长的一段,答案就是总长减去较长者

代码:

#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=1e5+7;


void solve(){
	int n;
	cin>>n;
	vector<int> a(n+1);
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int l=1;
	while(l<=n&&a[l]==a[1]){
		l++;
	}
	int r=n;
	while(r>=1&&a[r]==a[n]){
		r--;
	}
	int ans=n;
	//cout<<l<<" "<<n-r<<endl;
	if(a[1]==a[n]){
		ans-=l-1;
		ans-=n-r;
	}
	else{
		ans-=max(l-1,n-r);
	}
	cout<<max(0,ans)<<endl;
} 

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

D. Divisible Pairs

题意:给定x和y,对于长度为n的数组a,其中有ai+aj可以整除x并且ai-aj可以整除y为一对,统计有多少对这样的数字。

思路:有ai+aj=x,ai-aj=y,可以得到ai%x+aj%x=x%x && ai%y=aj%y  -> aj%x=(x-ai%x)%x ai%y=aj%y 所以对于i<j,在到达j的时候我们应该已经统计好对应的x-ai%x ai%y的值了,用map存一下就行。

代码:

#include <bits/stdc++.h>
#define ll long long
//#define endl '\n'
using namespace std;
const int N=1e5+7;


void solve(){
	int n,x,y;
	cin>>n>>x>>y;
	vector<int> a(n);
	for(int i=0;i<n;i++) cin>>a[i];
	ll ans=0;
	map<pair<int,int>,int> q;
	for(int i=0;i<n;i++){
		ans+=q[make_pair((x-a[i]%x)%x,a[i]%y)];
		q[make_pair(a[i]%x,a[i]%y)]++;
	}
	cout<<ans<<endl;
} 

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

E. Anna and the Valentine's Day Gift

题意:给出一个包含n个数字的数组a,Anna先操作,可以翻转一个数字(翻转后去除前导零),Sasha后操作,可以拼接用任意顺序俩个不同的数字再放回原来的数字,问最后数字的大小是否超过10^m。

思路:10^m其实只要看最后的数字位数有没有m位就可以了,对于俩人的操作,Anna是尽可能的将后面0多的翻转就可以消掉更多位数,Sasha拼接的时候让后面0多的拼到中间就不会被减少位数了。所以对于数组的排序就是看数字后面的零的数量来排序。

代码:

#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=5e5+7;
int n,m;

void solve(){
	cin>>n>>m;
	vector<string> q;
	for(int i=0;i<n;i++){
		string s;
		cin>>s;
		q.push_back(s);
	}
	vector<int> num(n);
	for(int i=0;i<n;i++){
		int cnt=0;
		string temp=q[i];
		for(auto it=temp.rbegin();it!=temp.rend()&&*it=='0';it++){
			num[i]++;
		}
	}
	ll all=0;
	for(int i=0;i<n;i++){
		all+=q[i].size()-num[i];
	}
	sort(num.begin(),num.end());
	reverse(num.begin(),num.end());
	for(int i=0;i<n;i++){
		if(i&1) all+=num[i];
	}
	if(all-1>=m){
		cout<<"Sasha"<<endl;
	}
	else cout<<"Anna"<<endl;
}

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

F. Chat Screenshots

题意:总共有n个人,其中k个人看到了排序,第i个人看到自己的位置肯定是第一的,问综合大家看到的排序是否可能存在。

思路:对于每一个看到的,第一个位置是不可信的,其他位置可以信任,那么由此可以建立一个图,从2->3的位置建图类推,注意重复的边不加入,然后拓扑排序跑一遍看是否能为n的点就知道是不是合理的了。

代码:

#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
const int N=2e5+7;
int n,k;
vector<int> q[N];
int in[N];
void solve(){
	cin>>n>>k;
	memset(in,0,sizeof(in));
	for(int i=0;i<=n;i++) q[i].clear();
	map<pair<int,int>,int> mp;
	
	for(int j=1;j<=k;j++){
		vector<int> a(n);
		for(int i=0;i<n;i++){
			cin>>a[i];
		}
		for(int i=2;i<n;i++){
			if(mp.find(make_pair(a[i-1],a[i]))==mp.end()){
				mp[make_pair(a[i-1],a[i])]++;
				q[a[i-1]].push_back(a[i]);
				in[a[i]]++;
			}
		}
	}
	//cout<<mp.size()<<endl;
	queue<int> line;
	int cnt=0;
	for(int i=1;i<=n;i++){
		if(in[i]==0){
			line.push(i);
			cnt++;
		}
	}
	while(!line.empty()){
		auto temp=line.front();
		line.pop();
		for(auto it:q[temp]){
			if(--in[it]==0){
				line.push(it);
				cnt++;
			}
		}
	}
	cout<<(cnt==n?"YES":"NO")<<endl;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃芒果的蘑菇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值