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

A. Turtle Puzzle: Rearrange and Negate

题意:给你n个数字,你可以随意排序这些数字,并且可以找到一个区间,将区间和的正负翻转,请问能得到最大的和是多少。
题解:很容易发现,不管怎么样排序都可以将负数放到一起,然后翻转,答案就是全部数字的绝对值之和。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e6 + 7 ;
const int mod = 998244353 ;
inline int read() {
	int 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 ;
}

int t , a[maxn] , n , rt ;
char c , s[maxn] ;
void solve(){
	n = read() ;
	ll sum = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
		sum += abs(a[i]) ;
	}
	cout << sum << endl ;
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

B. Turtle Math: Fast Three Task

题意:给你n个数字,有两种操作,一个是删除其中一个数字,一个是将一个数字加一,问能让所有数字之和被3整除的最小操作数。
题解:我们可以发现,所有数字模3以后,只会出现 0,1,2三个数字,那么可以想到,该序列的最大操作就是最多加2,也就是2个操作,那如果说删除一个数字,那么只能进行1次操作以下的操作才能让最小操作数最小,那么就很明显了,枚举每个数字,取最小值即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e6 + 7 ;
const int mod = 998244353 ;
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 , a[maxn] , n , m , k ;
char c , s[maxn] ;
vector < int > q[maxn] ;
ll Pow(ll x , ll y){
	ll cnt = 1 ;
	while(y){
		if(y % 2)
			cnt = cnt * x ;
		x = x * x ;
		y /= 2 ;
	}
	return cnt ;
}
void solve(){
	n = read() ;
	ll sum = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
		sum += a[i] ;
	}
	ll ans = (sum + 3 - 1) / 3 ;
	ans = (ans * 3) - sum ;
	for(int i = 1 ; i <= n ; i ++){
		sum -= a[i] ;
		ll res = (sum + 3 - 1) / 3 ;
		res = (res * 3) - sum ;
		ans = min(ans , res + 1) ;
		sum += a[i] ;
	}
	cout << ans << endl ;
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

C. Turtle Fingers: Count the Values of k

题意:给你三个数字a , b , l ,看看有多少个k可以满足l = k * a^{x} * b^{y}
题解:因为l只有1e6,所以最大才枚举到20,直接枚举即可,复杂度怎么都能过。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e6 + 7 ;
const int mod = 998244353 ;
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 , a[maxn] , n , m , k ;
char c , s[maxn] ;
void solve(){
	n = read() ;
	m = read() ;
	k = read() ;
	set < ll > q ;
	for(ll i = 0 ; i <= 20 ; i ++){
		for(ll j = 0 ; j <= 20 ; j ++){
			if(pow(n , i) > 1000000 || pow(m , j) > 1000000){
				break ;
			}
			ll res = pow(n , i) * pow(m , j) ;
			if(k % res == 0){
				q.insert(k / res) ;
			}
		}
	}
	cout << q.size() << endl ;
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

D. Turtle Tenacity: Continual Mods

题意:给你n个数字,看看能否找到一个排列,可以使a_i \mod a_{i + 1} \mod ...a_{n - 1} \mod a_n != 0
题解:只有两种情况,一种就是最小的数字的数量大于等于2并且是1,或者最小的数字大于等于2并且其他的数字全是他的倍数,其他的都是可以找到排列可以使模数不等于0的。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e6 + 7 ;
const int mod = 998244353 ;
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 , a[maxn] , n , m , k ;
char c , s[maxn] ;
vector < int > q[maxn] ;
ll Pow(ll x , ll y){
	ll cnt = 1 ;
	while(y){
		if(y % 2)
			cnt = cnt * x ;
		x = x * x ;
		y /= 2 ;
	}
	return cnt ;
}
void solve(){
	n = read() ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
	}
	sort(a + 1 , a + n + 1) ;
	ll ans = 1 ;
	for(int i = 2 ; i <= n ; i ++){
		if(a[i] == a[1]){
			ans ++ ;
		}
		else{
			break ;
		}
	}
	bool flag = 0 ;
	for(int i = 2 ; i <= n ; i ++){
		if(a[i] % a[1] != 0){
			flag = 1 ;
		}
	}
	if(((ans >= 2) && a[1] == 1) || (ans >= 2 && flag == 0)){
		cout << "NO\n" ;
		return ;
	}
	else{
		cout << "YES\n" ;
	}
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

E. Turtle vs. Rabbit Race: Optimal Trainings

题意:给你n个数字,m个查询,每个查询给你一个l一个k,你要找到一个r满足l <= r <= n并且让k - (sum[r] - sum[l - 1]) +1 <= i <= k的和最大。如果区间和大于k,那么会加负数,问最大值的最小的r是多少。
题解:很容易想到二分,直接二分找到r的边界,然后再加一些细节处理即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 2e6 + 7 ;
const int mod = 998244353 ;
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 , a[maxn] , n , m , k , sum[maxn] ;
void solve(){
	n = read() ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
		sum[i] = sum[i - 1] + a[i] ;
	}
	m = read() ;
	for(int i = 1 ; i <= m ; i ++){
		ll u , v ;
		u = read() ;
		v = read() ;
		ll l = u , r = n , ans = -1 ;
		while(l <= r){
			ll mid = (l + r) / 2 ;
			if(sum[mid] - sum[u - 1] <= v){
				l = mid + 1 ;
				ans = mid ;
			}
			else{
				r = mid - 1 ;
			}
		}
		if(ans == -1){
			cout << u << endl ;
			continue ;
		}
		if(ans == n){
			cout << ans << endl ;
			continue ;
		}
		if(sum[ans] - sum[u - 1] < v + 1){
			ll res = sum[ans] - sum[u - 1] ;
			ll Ans = ((v + (v - res + 1)) * res) / 2ll ;
			ll Res = sum[ans + 1] - sum[u - 1] ;
			Res = v - (Res - (v + 1)) ;
			ll Ans1 = ((v + (v - Res + 1)) * Res) / 2ll ;
			if(Ans >= Ans1 || Res <= 0){
				cout << ans << endl ;
				continue ;
			}
			else{
				cout << ans + 1 << endl ;
				continue ;
			}
		}
		cout << ans << endl ;
	}
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

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

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小小许愿瓶

我的成长我做主

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

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

打赏作者

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

抵扣说明:

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

余额充值