1. 程式人生 > >Debate (Codeforces 1070F)

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;
}