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;