[Daily] 20200601

C题.[Codeforces 1038C] Gambling

题目链接

思路: 按照题意模拟,用两个大根堆存a和b数组。
player A的决策:
①若a堆空,则删b堆中的最大值
②若b堆空,则取a堆中的最大值
③若a堆和b堆都未空
-----若a中最大值大于b中最大值,取a堆中的最大值
-----若a中最大值小于b中最大值,删b堆中的最大值
player B的决策:就是把上面的a,b交换
最后输出取的sumA和sumB的差

//AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
int n;
ll suma,sumb,x,cnt;
priority_queue<ll>a;
priority_queue<ll>b;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%lld",&x),a.push(x);
	for(int i=1;i<=n;i++)scanf("%lld",&x),b.push(x);
	while(cnt<n){
		cnt++;
		if(a.empty())b.pop();else
		if(b.empty()){suma+=a.top();a.pop();}else
		{
			ll ta=a.top(),tb=b.top();
			if(ta>=tb){//A
				suma+=ta;
				a.pop();
			}else b.pop();
		}
		if(b.empty())a.pop();else
		if(a.empty()){sumb+=b.top();b.pop();}else
		{
			ll ta=a.top(),tb=b.top();
			if(tb>=ta){
				sumb+=tb;
				b.pop();
			}else a.pop();
		}
	}
	cout<<suma-sumb;

D题.[Codeforces 1038C] Slime

题目链接

思路:
一、如果序列中有正有负,或者序列中有0,则所有数都可以取正的贡献,即总贡献为 所有数的绝对值之和
二、如果序列中全为正或者全为负,肯定有一个数不能取正的贡献(即让它减去它旁边的数,或者让它旁边的数减去它,使序列变成有正有负的情况),总贡献为(所有数的绝对值值和 - 这个数的绝对值*2),所以为了使总贡献最大,这个数应该取所有数中绝对值最小的数。即总贡献为(所有数的绝对值值和 - 绝对值最小的数的绝对值 *2)
注意特判只有一个数的情况

//AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+7;
int n;
ll ans,a[N],p,np,sum;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		if(a[i]>=0)p=1;
		if(a[i]<=0)np=1;
		sum+=llabs(a[i]);
	}
	if(n==1)ans=a[1];else
	if(p&&np)ans=sum;else
	{
		ll t=LLONG_MAX;
		for(int i=1;i<=n;i++)t=min(t,llabs(a[i]));
		ans=sum-2*t;
	}
	cout<<ans;

猜你喜欢

转载自blog.csdn.net/qq_45530271/article/details/106481608