Investigating Legions(想法 不确定问题)

https://ac.nowcoder.com/acm/contest/5669/I

题意:

n个人,m(未知)个团,给出两两是否属于相同团。但是有1/S的几率给出的是错误的(01互换)。问最后哪些人属于一个团。
输出按照字典序最小来,人数比和团数比为1:30。

解析:

很玄学,这题数据是随机生成的。

由于保证了一个团大致有至少30个点,所以可以这么做:

可以选择一个点,和他为1的先加进去,然后去掉和其他点0较多的点,再加入和团内点1较多的点

代码:

/*
 *  Author : Jk_Chen
 *    Date : 2020-07-20-12.25.15
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<"> "<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
 
char x[90000];
bool same[309][309];
vector<int>V[20];
 
int ans[309];
int pos[309];
 
 
 
#define test_
int main(){
#ifndef test
    int t=rd;
    while(t--){
        int n=rd,s=rd;
        scanf("%s",x);
        int ar=0;
        rep(i,0,n-1){
            rep(j,i+1,n-1){
                same[i][j]=same[j][i]=(x[ar++]=='1');
            }
        }
 
        int cnt=0;
        unordered_set<int>S,tmp,res;
        rep(i,0,n-1)S.insert(i);
 
        while(S.size()){
            int p=*S.begin();
 
            tmp.clear();
            tmp.insert(p);
 
            for(auto q:S){
                if(same[p][q]){
                    tmp.insert(q);
                }
            }
 
            for(int epoch=1;epoch<=3;epoch++){
                res.clear();
                // 去不同
                for(auto p:tmp){
                    int like=0,dislike=0;
                    for(auto q:tmp){
                        if(p==q)continue;
                        if(same[p][q])like++;
                        else dislike++;
                    }
                    if(like>dislike)
                        res.insert(p);
                }
                // 加同
                for(auto p:S){
                    if(res.count(p))continue;
                    int like=0,dislike=0;
                    for(auto q:res){
                        if(same[p][q])like++;
                        else dislike++;
                    }
                    if(like>dislike)
                        res.insert(p);
                }
                tmp=res;
            }
 
            cnt++;
            V[cnt].clear();
            for(auto p:res){
                S.erase(p);
                V[cnt].pb(p);
                pos[p]=cnt;
            }
        }
 
        mmm(ans,-1);
        int top=0;
        rep(i,0,n-1){
            if(ans[i]==-1){
                for(auto p:V[pos[i]]){
                    ans[p]=top;
                }
                top++;
            }
        }
        rep(i,0,n-1){
            printf("%d%c",ans[i]," \n"[i==n-1]);
        }
    }
#else
 
    int be[309];
    int n=300,m=9,S=20;
 
    rep(i,0,n-1){
        be[i]=rand()%m;
    }
    rep(i,0,n-1)rep(j,i+1,n-1){
        int s=(be[i]==be[j]);
        int r=rand()%S==0;
 
    }
 
 
#endif // test
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/107582112