Codeforces Round #840 (Div. 2) and Enigma 2022 - Cybros LNMIIT (A-C)

Dashboard - Codeforces Round #840 (Div. 2) and Enigma 2022 - Cybros LNMIIT - Codeforces

A. Absolute Maximization

题意:给定一个长度为n的数组a,可以执行该操作任意次:选第 i 个和第 j 个数交换两者二进制下第 b 位。 确定 max(a)- min(b) 的最大值。

思路:使最大值尽可能大最小值尽可能小,对于最大值二进制每一位,如果所有数该位上有1,则最大值这一位肯定能通过交换得到1,使最大值尽可能的得到1即能使尽可能地的大。最小值同理,使其尽可能的得到0即能使其尽可能的小。故答案为 所有数的或-与

#include<bits/stdc++.h>
// #define int long long 
#define PII pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cin.tie(0)

using namespace std;

const int N=1e5+10;

int n;
int a[N];

void solve(){
	cin >> n;
	for(int i=0;i<n;i++) cin >> a[i];
	int num=a[0];
	int num1=num;
	for(int i=0;i<n;i++){
		num|=a[i];
		num1&=a[i];
	}
	cout << num-num1 << endl;
}

signed main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
}

B. Incinerate

题意:有 n 只怪物,每只怪物的血量和力量分别为 ai 和 bi,玩家攻击力初始为k,每次攻击可以攻击所有怪物使其血量减小k(怪物血量<=0为死亡),同时玩家的攻击力减少所有存活怪物里最小的力量,问玩家是否可以击杀所有怪物。

思路:(1)用优先队列维护怪物的力量即可(小根堆),记录打出的攻击和,若当前对头的怪物血量小于等于攻击和(死掉了)弹出,否则当前怪物的力量就是下次攻击要减少的值,若攻击和大于等于最大怪物血量则YES,若k<0 且此时攻击和还未大于等于最大怪物血量则NO,模拟此过程即可。

#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cin.tie(0)

using namespace std;

const int N=1e5+10;

int n,k;
int a[N],b[N];
PII p[N];

void solve(){
	cin >> n >> k;
	int mx=-1;
	priority_queue<PII, vector<PII>, greater<PII>> q;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		p[i].second=a[i];
		mx=max(mx,a[i]);
	}
	for(int i=1;i<=n;i++){
		cin >> b[i];
		p[i].first=b[i];
		q.push(p[i]);
	}
	int sum=0;
	while(k>0){
		sum+=k;
		if(sum>=mx){
			cout << "YES" << endl;
			return ;
		}
		while(q.size()>0 && q.top().second<=sum ){
			q.pop();
		}
		int res=q.top().first;
		k-=res;
	}
	cout << "NO" << endl;
	
}

signed main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
}

C. Another Array Problem

题意:给定一个长度为n的数组a,可以执行以下操作任意次:选择两个位置 i ,j ,使[ai—aj]全部变为abs(ai-aj)。问可以得到的最大数组和。

思路:最优的情况下可以将每个数变为数组的最大值使其和最大,可以发现当(n>3)若最大值在最左\右侧时可以将数组中所有数变为最大值,而(n>4)时无论最大值在哪个地方都可将数组中所有数变为最大值(如[1,2,9,4] ->[1,1,9,4]->[0,0,9,4]->[9,9,9,4]->....[9,9,0,0]->[9,9,9,9]),故当n>4,答案为max*n,当n<4,枚举所有情况即可。

#include<bits/stdc++.h>
#define int long long 

using namespace std;

const int N=2e5+10;

int n;
int a[N];

void solve(){
	cin >> n;
	
	int mx=-1;
	int sum=0;
	
	for(int i=1;i<=n;i++){
		cin >> a[i];
		mx=max(mx,a[i]);
		sum+=a[i];
	}
	
	if(n>3) {
		int ans=mx * n;
		cout << ans << endl;
		return ;
	}
	else if(n==2){
		int res=abs(a[1]-a[2])*2;
		int ans=max(sum,res);
		cout << ans << endl;
	}
	else{
		if(a[1]==mx || a[3]==mx) { //最大值在两侧,答案就是mx*3
			int ans=mx * 3;
			cout << ans << endl;
			return ; 
		}
		int res1=max(abs(a[1]-a[2]),a[3]) * 3; //对于i=1,j=2操作,答案就是两侧的最大值*3
		int res2=max(abs(a[2]-a[3]),a[1]) * 3; //对于i=2,j=3操作,答案就是两侧的最大值*3
		int res3=abs(a[3]-a[1]) * 3; //对于i=1,j=3操作,答案就是abs(a[1]-a[3])*3;
		int ans=max(max(sum,res1),max(res1,res2)); //输出最大值即可
		cout << ans << endl;
	}
}

signed main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值