CSP-S 2025 T1 [社团招新]解题报告
OI生涯之殇
场上被这道题硬控2h,最后只能打完性质分和暴力分仓皇离场
我的OI生涯的最后一场比赛就这么以一种极度恶心的方式落幕了
切入
我们首先要注意到$ n\geq 10^5$,这意味着 \(dp\)是不可行的,因此,我们要考虑贪心
解决
根据约束条件$ cnt_i \leq n/2$我们可以想到先贪心地取每个组的最大值,如果该方案合法,就输出结果
那如果不合法呢?
此时我们就要考虑反悔
可以使用优先队列存每组次大值与最大值的差值,这样就可以在超出 \(n/2\)的组上对原有的 \(ans\)进行一个减法,直到该组合法
由于约束条件为 \(cnt_i \leq n/2\),我们可以推断出最多只有一个组是不合法的,故而能够证明这样的反悔是合法的
为什么考场上我就没有想出来呢......
AC Code
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define endll " "
#define fre(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
#define pii pair<int,int>
#define pb push_back
#define eb emplace_back
#define it inline int
#define iv inline void
#define ib inline bool
#define sakura_no_uta return 0
#pragma GCC optimize(0)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
using namespace std;
const int MAXN=500050;
const int INF=0x3f3f3f3f3f3f3f3f;
const int MOD=998244353;
it gcd(int x,int y) {return y==0?x:gcd(y,x%y);}
it lcm(int x,int y) {return y/gcd(x,y)*x;}
it max(int x,int y) {return x>y?x:y;}
it min(int x,int y) {return x<y?x:y;}
it ksm(int x,int m,int mod)
{
int res=1,bas=x%mod;
while(m)
{
if(m&1)
res=(res*bas)%mod;
bas=(bas*bas)%mod;
m >>= 1;
}
return res;
}
int n,m,l,r,u,v,w,cnt,tot,ans,cnt1,cnt2,cnt3,lim,T;
struct lane
{
int a,b,c,maxn;
}t[MAXN];
priority_queue<int> f,g,h;
signed main()
{
fre("club");
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> T;
while(T--)
{
cin >> n;
memset(t,0,sizeof(t));
ans=0;
cnt1=0;
cnt2=0;
cnt3=0;
lim=n/2;
for(int i=1;i<=n;i++)
{
cin >> t[i].a >> t[i].b >> t[i].c;
t[i].maxn=max(t[i].a,max(t[i].b,t[i].c));
if(t[i].a==t[i].maxn)
{
cnt1++;
ans+=t[i].maxn;
f.push(max(t[i].b-t[i].a,t[i].c-t[i].a));
}
else
{
if(t[i].b==t[i].maxn)
{
cnt2++;
ans+=t[i].maxn;
g.push(max(t[i].a-t[i].b,t[i].a-t[i].b));
}
else
{
cnt3++;
ans+=t[i].maxn;
h.push(max(t[i].a-t[i].c,t[i].b-t[i].c));
}
}
}
while(cnt1>lim)
{
ans+=f.top();
f.pop();
cnt1--;
}
while(cnt2>lim)
{
ans+=g.top();
g.pop();
cnt2--;
}
while(cnt3>lim)
{
ans+=h.top();
h.pop();
cnt3--;
}
while(!f.empty())
f.pop();
while(!g.empty())
g.pop();
while(!h.empty())
h.pop();
cout<<ans<<endl;
}
sakura_no_uta;
}

浙公网安备 33010602011771号