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