T1:
题解:
考试的时候写了O(nmlog(ans))的做法得了80pts
80pts:
先二分答案,然后对于每个人可以打到的怪物连边跑二分图匹配
100pts:
人的数量肯定大于等于怪物的数量
s点把数轴划分成了两部分,每个部分内互相打击是最优的
如果一部分的人很多,我们就从另一部分调一点过来
调过来的肯定要离s近一点啊,这样对于哪边都比较优
那么怎么确定每个人打哪个呢?以s为中心排序!
位于同一部分的怪物和人,排名相同的互相打击
算是贪心吧
代码:
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
struct ll{int w;};
struct rr{int w;};
priority_queue<ll>ql[2];
priority_queue<rr>qr[2];
bool operator <(const ll &a,const ll &b){return a.w<b.w;}//弹出来坐标最大的
bool operator <(const rr &a,const rr &b){return a.w>b.w;}//弹出来坐标最小的
int n,m,s;
int main()
{
freopen("kill.in","r",stdin);
freopen("kill.out","w",stdout);
int i,p,ans=0;int cnt1=0,cnt2=0;
scanf("%d%d%d",&n,&m,&s);
for (i=1;i<=n;i++)
{
scanf("%d",&p);
if (p<=s) ql[0].push((ll){p}),cnt1++;
else qr[0].push((rr){p}),cnt2++;
}
for (i=1;i<=m;i++)
{
scanf("%d",&p);
if (p<=s) ql[1].push((ll){p}),cnt1--;
else qr[1].push((rr){p}),cnt2--;
}
while (cnt1>0)//人多了
{
rr t=qr[1].top(); qr[1].pop();
cnt1--;
ql[1].push((ll){t.w});
}
while (cnt2>0)//人多了
{
ll t=ql[1].top(); ql[1].pop();
cnt2--;
qr[1].push((rr){t.w});
}
while (!ql[0].empty())
{
ll t1=ql[0].top(),t2=ql[1].top();
ans=max(ans,abs(t1.w-t2.w)+abs(t2.w-s));
ql[0].pop(); ql[1].pop();
}
while (!qr[0].empty())
{
rr t1=qr[0].top(),t2=qr[1].top();
ans=max(ans,abs(t1.w-t2.w)+abs(t2.w-s));
qr[0].pop(); qr[1].pop();
}
printf("%d",ans);
}

本文解析了一道比赛算法题目,介绍了如何使用贪心算法求解最优解,并给出了具体实现代码。通过对人员和怪物的位置进行合理分配,实现了攻击距离的最大化。
731

被折叠的 条评论
为什么被折叠?



