Debate (Codeforces 1070F)

题目链接: http://codeforces.com/contest/1070/problem/F

思路: 先把11的选上,然后01和10的选min(投01和10的人的个数),最后计算是否还可以再选入,然后从剩下的人当中选择影响力大的。

#include<cstdio>
#include<iostream>
#include<cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1e6;
struct A
{
    int a,b=0;    //这里可以用int型存储,比较方便
}s10[MAXN],s01[MAXN],s00[MAXN];
bool cmp(A x,A y)
{
    return x.b>y.b;
}
int main()
{
    int n,ans=0;
    cin>>n;
    int e11=0,e10=0,e01=0,e00=0;
    for(int i=0;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        if(x==11){
            ans+=y;e11++;  //投11的人一定会被选上,所以只需要记下影响力和人数就可以了
        }
        if(x==10){
            s10[e10].a=x;s10[e10].b=y;e10++;
        }
        if(x==1){
            s01[e01].a=x;s01[e01].b=y;e01++;
        }
        if(x==0){
            s00[e00].a=x;s00[e00].b=y;e00++;
        }
    }
    sort(s10,s10+e10,cmp);   //先对s01和s10按影响力从大到小排序
    sort(s01,s01+e01,cmp);
    int minn=min(e01,e10);   
    for(int i=0;i<minn;i++)
    {
        ans+=s10[i].b+s01[i].b;
    }
    int all=(e11+minn)*2;   //计算可以选上的总人数
    int k=all-e11-minn*2;   //k为还可以选的人数
    if(e10>e01)
    {
        for(int i=minn;i<e10;i++)     //把s01或者s10中剩余的人数加到s00中,方便排序
            s00[e00++]=s10[i];
    }
    else
    {
        for(int i=minn;i<e01;i++)
            s00[e00++]=s01[i];
    }
    sort(s00,s00+e00,cmp);    //此时s00中还存有s10或s01中剩余的人,然后排序
    for(int i=0;i<k;i++)
    {
        ans+=s00[i].b;         //不需要考虑怎么投的票了,只需要选择影响力大的就可以了
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Septembre_/article/details/83241862