C. Basic Diplomacy 思维

C. Basic Diplomacy 思维

题目大意:

你有 (n) 个朋友,你休息 (m) 天,每天都有一部分朋友有空,你每天可以选择一个朋友来陪你,但是如果有一个朋友陪你的天数大于 (m/2) 向上取整,那么就会让别人神奇。

希望你帮他做出一种选择,没有一个人陪他的天数大于 (m/2) 向上取整,如果可以,输出 (YES) 和每一天陪他的人,如果不行,输出 (NO)

题解:

  • 首先因为是只要不大于 (m/2) 的向上取整
  • 那么其实只要只有1个人有空的天数小于等于 (m/2) (同一个人)就是 YES
  • 然后按照每一天的人数的 size 从小到大即可
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int p[maxn],vis[maxn],ans[maxn];
vector<int>a[maxn];
void init(int n){
    for(int i=0;i<=n;i++) p[i] = i,a[i].clear(),vis[i] = 0;
}
bool cmp(int i,int j){
    return a[i].size()<a[j].size()?true:false;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);init(max(n,m));
        for(int i=1,x,y;i<=m;i++){
            scanf("%d",&x);
            while(x--){
                scanf("%d",&y);
                a[i].push_back(y);
            }
        }
        sort(p+1,p+1+m,cmp);
        for(int i=1;i<=m;i++){
//            printf("p[%d]=%d
",i,p[i]);
            int u = p[i],pos = 0;
            for(int j=1;j<a[u].size();j++){
                if(vis[a[u][j]]<vis[a[u][pos]]) pos = j;
            }
//            printf("i = %d u = %d %d
",i,u,a[u][pos]);
            ans[u] = a[u][pos];
            vis[a[u][pos]]++;
        }
        int len = (m+1)/2,flag = 1;
        for(int i=1;i<=n;i++) if(vis[i]>len) flag = 0;
        if(!flag) printf("NO
");
        else{
            printf("YES
");
            for(int i=1;i<=m;i++) printf("%d ",ans[i]);
            printf("
");
        }
    }
}
/*
100
5 6
3 1 2 3
2 1 2
1 1
1 1
1 1
2 1 2
 */
原文地址:https://www.cnblogs.com/EchoZQN/p/14579172.html