链接:https://vjudge.net/contest/400607#problem/I
思路:思路还是很简单的,要么把所有的防卫都打掉,要么留下所有的防卫。剩下就是些细节问题啦
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e5+7;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
bool cmp(int x, int y){
return x > y;
}
struct Node{
int x, g;
bool operator < (const Node n1) {
return x < n1.x;
}
}b[maxn];
set<int> st1;
map<int, int> mp1;
int a[maxn];
vector<int> df, udf;
signed main()
{
int t, cnt = 0;
scanf("%d",&t);
while(t--)
{
int n = read(), m = read();
mp1.clear(); df.clear(); udf.clear(); st1.clear();
for(int i = 0; i < n; i++) {
a[i] = read();
if(!mp1[a[i]]) st1.insert(a[i]);
mp1[a[i]]++;
}
sort(a, a+n, cmp);
for(int i = 1; i <= m; i++) {
b[i].x = read();
}
for(int i = 1; i <= m; i++) {
b[i].g = read();
}
int ans1 = 0, ans2 = 0; //ans1是守卫全死,ans2是守卫全活
sort(b+1, b+m+1);
for(int i = m; i >= 1; i--) {
if(b[i].g == 0) udf.push_back(b[i].x);
else df.push_back(b[i].x);
}
int sz;
//op1
bool flag = 1;
sz = df.size();
for(int i = 0; i < sz; i++) {
auto it = st1.lower_bound(df[i]);
if(it == st1.end()) {
flag = 0;//守卫全死这种情况不存在
ans1 = 0;
break;
}
mp1[*it]--;
if(mp1[*it] == 0) {
st1.erase(*it);
}
}
if(flag)
{
bool flag1 = 1;
sz = udf.size();
for(int i = 0; i < sz; i++) {
auto it = st1.lower_bound(udf[i]);
if(it == st1.end()) {
flag1 = 0;
break; //剩余的都不能造成伤害
}
mp1[*it]--;
ans1 += *it-udf[i];
if(mp1[*it] == 0) {
st1.erase(*it);
}
}
if(!st1.empty() && flag1)
{
for(auto it : st1) {
ans1 += mp1[it]*it;
}
}
}
//op2
sz = udf.size();
sort(udf.begin(), udf.end());
for(int i = 0; i < sz && i < n; i++) {
if(a[i] >= udf[i]) {
ans2 += a[i]-udf[i];
}
else break;
}
printf("Case %d: %d\n",++cnt, max(ans1, ans2));
}
return 0;
}
京公网安备 11010502036488号