Codeforces Round 925 (Div. 3) A - E 题解

A. Recovering a Small String

题意:问给你一个n,找到字符串序列最小的三个字母。
题解:贪心即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e5 + 7 ;
inline ll read(){
	ll x = 0 , f = 1 ;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
ll t , n , m , k , a[maxn] , c[maxn] , b[maxn] ;
char s[maxn] ;
void solve(){
	n = read() ;
	ll x = 3 ;
	c[1] = 1 ;
	c[2] = 1 ;
	c[3] = 1 ;
	if(x + 25 <= n){
		c[3] = 26 ;
		x += 25 ;
	}
	else{
		cout << char(c[1] + 'a' - 1) << char(c[2] + 'a' - 1) << char(c[3] + (n - x) + 'a' - 1) << endl ;
		return ;
	}		
	if(x + 25 <= n){
		c[2] = 26 ;
		x += 25 ;
	}
	else{
		cout << char(c[1] + 'a' - 1) << char(c[2] + (n - x) + 'a' - 1) << char(c[3] + 'a' - 1) << endl ;
		return ;
	}
	cout << char(c[1] + (n - x) + 'a' - 1) << char(c[2] + 'a' - 1) << char(c[3] + 'a' - 1) << endl ;
} 
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

B. Make Equal

题意:给你n个数字,n个数字求和一定会被n整除,可以操作(1 <= i < j <= n)并且使a_i - 1 , a_j + 1。看看能否将所有数字变成一样的。
题解:贪心即可,如果数字大于sum / n ,那么就累计,如果数字小于sum / n , 那么就看看累计的数字能不能填补即可,如果不行输出NO。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e5 + 7 ;
inline ll read(){
	ll x = 0 , f = 1 ;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
ll t , n , m , k , a[maxn] , c[maxn] , b[maxn] ;
char s[maxn] ;
void solve(){
	n = read() ;
	ll sum = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
		sum += a[i] ;
	}
	sum /= n ;
	ll res = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		if(a[i] < sum){
			if((sum - a[i]) > res){
				cout << "NO\n" ;
				return ;
			}
			else{
				res -= (sum - a[i]) ;
			}
		}
		else{
			res += (a[i] - sum) ;
		}
	}
	cout << "YES\n" ;
} 
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

C. Make Equal Again

题意:给你n个数字,看看能不能找到(1 <= i < j <= n)并且覆盖此区间为x,只能进行一次操作,问最小的(j - i + 1)是多少。
题解:很明显,必须要从开头和结尾算起,找到从开头开始的相同序列的最长长度,找到从结尾开始的相同序列的最长长度,分别统计取max即可,详细细节请见代码。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e5 + 7 ;
inline ll read(){
	ll x = 0 , f = 1 ;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
ll t , n , m , k , a[maxn] , c[maxn] , b[maxn] ;
char s[maxn] ;
void solve(){
	n = read() ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
	}
	ll rt = n , Rt = 1 ;
	ll res = a[1] ;
	for(int i = 2 ; i <= n ; i ++){
		if(a[i] != res){
			rt = i - 1 ;
			break ;
		}
	}
	res = a[n] ;
	for(int i = n - 1 ; i >= 1 ; i --){
		if(res != a[i]){
			Rt = i + 1 ;
			break ;
		}
	}
	if(a[1] == a[n]){
		if(Rt <= rt){
			cout << 0 << endl ;
			return ;
		}
		cout << n - rt - (n - Rt + 1) << endl ;
		return ;
	}
	else{
		cout << n - max((n - Rt + 1) , rt) << endl ;
		return ;
	}
} 
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

D. Divisible Pairs

题意:给你n个数字还有一个x一个y,看能找到多少对(1 <= i < j <= n)(a_i + a_j)可以整除x并且(a_i - a_j)可以整除y。
题解:这是一个关于同余的问题,存入模数,用map统计即可,需要用到少许组合数知识。
代码:
void result() {
    cin >> n >> x >> y;
    map<int, vector< int > > mod_y;
    for (int i = 0; i < n ; i ++) {
        cin >> a[i] ;
        mod_y[a[i] % y].push_back(a[i] % x);
    }
    ll ans{} ;
    for (auto it : mod_y) {
        ll sum{} ;
        map< int , ll > cnt ;
        for (int i = it.S.size() - 1 ; i >= 0 ; i --) {
            if (it.S[i] == 0) {
                sum += (cnt[0]) ;
            }
            sum += (cnt[x - it.S[i]]) ;
            cnt[it.S[i]] ++ ;
        }
        ans += sum ;
    }
    cout << ans ;
}

E. Anna and the Valentine's Day Gift

题意:给你n个数字和一个数字m,有两个人,Anna和Sasha,Anna先操作,它会将一个数字的顺序逆转,Sasha的操作会挑选两个数字,将他们拼接起来,顺序随便。两个人的操作都是最佳操作,问最后剩下的数字如果小等于10的m次方,那么就是Anna赢,否则Sasha赢。
题解:看到这个题,很明显,要比较数字位数,那么就能想到如果一个数字后面有0,那么Anna操作会让0全部消失,那么就很明显了,这道题转换成了最多会减少多少个0,那么就很简单了,将所有数字的末尾0个数统计到优先队列里面,从大里面开始取,Anna操作就减去队顶的0的个数,Sasha操作就是可以保住队顶的0的个数,最后用总共的数字位数x -一共减去的0的个数和m + 1进行比较判断即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e5 + 7 ;
inline ll read(){
	ll x = 0 , f = 1 ;
	char c = getchar() ;
	while(c > '9' || c < '0'){
		if(c == '-')
			f = -1 ;
		c = getchar() ;
	}
	while(c >= '0' && c <= '9'){
		x = x * 10 + c - '0' ;
		c = getchar() ;
	}
	return x * f ;
}
ll t , n , m , k , a[maxn] , c[maxn] , b[maxn] ;
char s[maxn] ;
void solve(){
	n = read() ;
	m = read() ;
	priority_queue < ll , vector < ll > , less < ll > > q ;
	ll Ans = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
		ll res = a[i] , cnt = 0 ;
		while(1){
			if(res % 10 == 0){
				cnt ++ ;
				res /= 10 ;
			}
			else{
				break ;
			}
		}
		q.push(cnt) ;
		cnt = 0 ;
		res = a[i] ;
		while(res != 0){
			res /= 10 ;
			cnt ++ ;
		}
		Ans += cnt ;
	} 
	ll ans = 0 ;
	while(1){
		if(q.top() == 0 || q.empty()){
			break ;
		}
		ans += q.top() ;
		q.pop() ;
		if(q.empty()){
			break ;
		}
		q.pop() ;
	}
	if(Ans - ans < m + 1){
		cout << "Anna" << endl ;
		return ;
	}
	else{
		cout << "Sasha\n" ;
	}
} 
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

喜欢作者的记得关注点赞加收藏哦~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小小许愿瓶

我的成长我做主

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

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

打赏作者

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

抵扣说明:

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

余额充值