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

文章介绍了四个编程题目,涉及正方形面积计算、字符串字符替换最少操作、电量消耗与消息发送、数组差值最大化和棋盘游戏策略,展示了不同的算法和逻辑处理技巧。
摘要由CSDN通过智能技术生成

A. Square

题意:给你四个坐标点,求出正方形面积。
题解:直接计算即可,详细见代码。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 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] , b[maxn] , sum[maxn] ;
char s[maxn] ;
vector < int > v[maxn] ;
void solve(){
	map < ll , ll > mp , vis ;
	int cnt = 0 , Cnt = 0 ;
	for(int i = 1 ; i <= 4 ; i ++){
		ll u , v ;
		u = read() ;
		v = read() ;
		if(mp[u] == 0){
			b[++ cnt] = u ;
			mp[u] ++ ;
		}
		if(vis[v] == 0){
			a[++ Cnt] = v ;
			vis[v] ++ ;
		}
	}
	cout << abs(b[1] - b[2]) * abs(a[1] - a[2]) << endl ;
	
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

B. Arranging Cats

题意:给你两个字符串a和b,让a变成b的最少操作数是多少,一共有三个操作,第一个是可以将一个0变成1,第二个是可以将一个1变成0,第三个是可以交换s_is_j的位置。
题解:很明显,统计原始字符串和目标字符串的1的个数,如果原字符串的1多,那么就统计原字符串的1对应0的个数,如果是1对应1,那么两个字符串的1的个数都要减1。答案就是统计的数字加上两个字符串剩下1的差值。如果是目标字符串1多,操作相同。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 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] , b[maxn] , sum[maxn] ;
char s[maxn] , S[maxn] ;
vector < int > v[maxn] ;
void solve(){
	n = read() ;
	scanf("%s" , s + 1) ;
	scanf("%s" , S + 1) ;
	ll sum = 0 , Sum = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		if(s[i] == '1')
			sum ++ ;
	}
	for(int i = 1 ; i <= n ; i ++){
		if(S[i] == '1')
			Sum ++ ;
	}
	if(sum >= Sum){
		ll res = 0 ;
		for(int i = 1 ; i <= n ; i ++){
			if(S[i] == '1' && s[i] == '0'){
				res ++ ;
			}
			if(S[i] == '1' && s[i] == '1'){
				sum -- ;
				Sum -- ;
			}
		}
		cout << max(res , 0ll) + sum - Sum << endl ;
		return ;
	}
	else{
		ll res = 0 ;
		for(int i = 1 ; i <= n ; i ++){
			if(s[i] == '1' && S[i] == '0'){
				res ++ ;
			}
			if(s[i] == '1' && S[i] == '1'){
				sum -- ;
				Sum -- ;
			}
		}
		cout << max(res , 0ll) + Sum - sum << endl ;
		return ;
	}
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

C. Sending Messages

题意:给你n,f,a,b,和n个数字,一开始的起始时间是0,屏幕是亮着的,总电量为f。一共有两个操作,如果屏幕亮着,那么单位时间消耗a的电量。消耗b的电量可以实现关闭手机再打开的操作,并且可以在开启时同时完成发送消息操作。问f电量是否够发n条消息。特别注意,当手机电量为0时自动关闭,无法发送消息。
题解:那么很明显,设置啊a[0] = 0 ,枚举差值的大小,如果(c[i] - c[i - 1]) * a <= b,那么答案就加上(c[i] - c[i - 1]) * a,否则就加上b,统计答案即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 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 , f , u , v , a[maxn] , b[maxn] , sum[maxn] ;
char s[maxn] , S[maxn] ;
void solve(){
	n = read() ;
	f = read() ;
	u = read() ;
	v = read() ;
	a[0] = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
	}
	ll ans = 0 ;
	for(int i = 1 ; i <= n ; i ++){
		ans += min(v , (a[i] - a[i - 1]) * u) ;
	}
	if(ans < f){
		cout << "YES\n" ;
	}
	else{
		cout << "NO\n" ;
	}
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

D. Very Different Array

题意:给你一个n和m,两个数组a和b,求出\sum |a_i - c_i|的最大值,通俗的讲就是找到n个b和n个a的最大差值。
题解:这个题是明显的贪心,首先将a和b数组排序,用双指针,从最小值和最大值入手,用max(|a_l - b_L] , |a_l - b_R|)max(|a_r - b_L| , |a_r - b_R|)做比较,每次取最大的那边,然后统计答案差值即可。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 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 , f , u , v , a[maxn] , b[maxn] , sum[maxn] ;
char s[maxn] , S[maxn] ;
void solve(){
	n = read() ;
	m = read() ;
	for(int i = 1 ; i <= n ; i ++){
		a[i] = read() ;
	}
	for(int i = 1 ; i <= m ; i ++){
		b[i] = read() ;
	}
	sort(a + 1 , a + n + 1) ;
	sort(b + 1 , b + m + 1) ;
	ll  L = 1 , R = m , l = 1 , r = n , ans = 0 ;
	while(1){
		if(l > r){
			break ;
		}
		ll res = max(abs(a[l] - b[L]) , abs(a[l] - b[R])) ;
		ll Res = max(abs(a[r] - b[L]) , abs(a[r] - b[R])) ;
		if(res >= Res){
			ans += res ;
			if(abs(a[l] - b[L]) >= abs(a[l] - b[R])){
				L ++ ;
			}
			else{
				R -- ;
			}
			l ++ ;
		}
		else{
			ans += Res ;
			if(abs(a[r] - b[L]) >= abs(a[r] - b[R])){
				L ++ ;
			}
			else{
				R -- ;
			}
			r -- ;
		}
	}
	cout << ans << endl ;
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

E. Eat the Chip

题意:给你一个长方形,和两个坐标a和b,a是Alice,它只能(x_1 + 1, y_1),(x_1 + 1 , y_1 - 1) , (x_1 + 1 , y_1+ 1)走,b是Bob,它只能往(x_2 - 1 , y_2) , (x_2 - 1 , y_2 - 1) , (x_2 - 1 , y_2 + 1)走,如果谁走到对方占领的格子里即为获胜,如果双方有一个到达(x_1 == n || x_2 == 1),那么为平局。
题解:很明显,如果b点在a点的上面或者同行的话,为平局。再思考,很容易想到两个人纵坐标的距离差的奇偶是确认谁获胜的关键,那么先计算出(x_2 - x_1 - 1),如果为偶数,那么Alice有可能获胜,Bob一定不能获胜。如果为奇数,那么Bob有可能获胜,Alice一定不能获胜。那什么情况下为平局呢,很明显,为败者往反方向的墙面逃跑,如果和胜者相遇,那么无法平局,如果没法相遇,那么答案为平局。
代码:
#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll , ll > PII ;
const int maxn = 1e6 + 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 , xx , yy , x2 , y2 , a[maxn] , b[maxn] , sum[maxn] ;
char s[maxn] , S[maxn] ;
void solve(){
	n = read() ;
	m = read() ;
	xx = read() ;
	yy = read() ;
	x2 = read() ;
	y2 = read() ;
	if(x2 - xx - 1 < 0){
		cout << "Draw\n" ;
		return ;
	}
	ll res = x2 - xx - 1 ;
	if(abs(y2 - yy) == 0 || (res % 2 == 0 && abs(y2 - yy) == 1)){
		if(res % 2 == 1){
			cout << "Bob\n" ;
		}
		else{
			cout << "Alice\n" ;
		}
		return ;
	}
	if(res % 2 == 1){
		ll cnt ;
		if(y2 > yy){
			cnt = y2 - 1 ;
		}
		else{
			cnt = m - y2 ;
		}
		if((res / 2) >= cnt - 1){
			cout << "Bob\n" ;
		}
		else{
			cout << "Draw\n" ;
		}
		return ;
	}
	else{
		ll cnt ;
		if(yy > y2){
			cnt = yy - 1 ;
		}
		else{
			cnt = m - yy ;
		}
		if((res / 2) >= cnt - 1){
			cout << "Alice\n" ;
		}
		else{
			cout << "Draw\n" ;
		}
		return ;
	}
}
int main(){
	t = read() ;
	while(t --){
		solve() ;
	}
	return 0 ;
}

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

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小小许愿瓶

我的成长我做主

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

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

打赏作者

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

抵扣说明:

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

余额充值