C. Basic Diplomacy (Thinking + Sharing Greedy + Details)

https://codeforces.com/contest/1484/problem/C


Ideas:

Was greedy 5 times last night.

The original idea: to deal with the current number of each number has been taken several times, how many times can still be taken.

Code details: update after scanning the first layer.

We discussed in class at noon and found that there was a hack

3 6
3 1 2 3
3 1 2 3
3 1 2 3
1 1
1 1
1 1

The reason is that only 1 can be taken later, which leads to the wrong split.

So we deal with 1 day first. Update the status that has been taken and the status that can be taken for each number, and then return to the above average score, and take the least number of people currently taken at each level. If you look at the last one, don't take which one.

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
map<LL,LL>map1;///前面的
map<LL,LL>map2;///后面的
map<LL,LL>map3;///check
vector<LL>g[maxn];
vector<LL>v[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL t;cin>>t;
  while(t--){
    map1.clear();
    map2.clear();
    map3.clear();
    LL n,m;cin>>n>>m;

    for(LL i=0;i<m+10;i++) g[i].clear(),v[i].clear();

    for(LL i=1;i<=m;i++){
        LL k;cin>>k;
        for(LL j=1;j<=k;j++){
            LL x;cin>>x;
            g[i].push_back(x);
            map2[x]++;
        }
    }

    ///先处理一天的
    for(LL i=1;i<=m;i++){
        LL k=g[i].size();
        if(k==1){
            map1[g[i][0]]++;
            map2[g[i][0]]--;
            v[i].push_back(g[i][0]);
        }
    }


    for(LL i=1;i<=m;i++){

        LL num=0;LL cnt=0x3f3f3f3f;

        if(g[i].size()==1) continue;

        for(auto j:g[i]){


            if(cnt>map1[j]){
                cnt=map1[j];

                num=j;
            }
            else if(cnt==map1[j]){

                    if(map2[num]>map2[j]){

                        num=j;
                    }
            }
            ///扫完再加减
        }

        v[i].push_back(num);

        map1[num]++;

        for(auto j:g[i]){
            map2[j]--;
        }
    }

    for(LL i=1;i<=m;i++){
        for(auto j:v[i]){
            map3[j]++;
        }
    }

    LL num=(m+1)/2;
    bool flag=1;
    for(auto i:map3){
        if(i.second>num){
            flag=0;
            break;
        }
    }
    if(flag==0){
        cout<<"NO"<<"\n";
    }
    else{
        cout<<"YES"<<"\n";
        for(LL i=1;i<=m;i++){
            cout<<v[i][0]<<" ";
        }
        cout<<"\n";
    }
  }
return 0;
}


 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/115080951
Recommended