2020牛客暑期多校训练营(第四场)I Investigating Legions

2020牛客暑期多校训练营(第四场)I Investigating Legions

题意

I Investigating Legions
有N个点(30-300)和M(1~N/30)个团,每个点仅属于
一个团(等概率在0~M-1选择一个整数作为它的团)。
• 有一个常数 S(20~100)。按以下的方式生成 01 矩阵 a:
如果 i 和 j 属于同一个团,a[i][j]=1,否则a[i][j]=0。同时该
值有 1/S 的概率被翻转。
• 给出 N 和 S 和 a(M 不给出),要还原每个点属于的团。

题解

其实不是1/S,rand() can be considered as a uniform random function. i.e., select a integer from interval [0, \mathrm{lcm}(m, S)-1][0,lcm(m,S)−1] with equal probability.所以取个2就可以了。然后就暴力去找能连通超过m/2的点就可以了。读题啊,读题啊,读题啊,读题啊,读题啊,读题啊,读题啊。

代码

#include
typedef long long ll;
using namespace std;
#define N 305
int f[N][N];
char arr[N * N];
int a[N];
int main() {
	int t;
	scanf("%d", &t);
	while(t--) {
		int n, s;
		scanf("%d%d", &n, &s);
		scanf("%s", arr);
		int ct = 0;
		for(int i = 0; i < n; i++) {
			for(int j = i + 1; j < n; j++) {
				f[i][j] = f[j][i] = arr[ct++] - '0';
			}
			f[i][i] = 1;
		}
		fill(a, a + n + 1, -1);
		int id = 0;
		for(int i = 0; i < n; i++) {
			vector<int> v;
			if(a[i] == -1) {
				for(int j = 0; j < n; j++) {
					if(f[i][j] && a[j] == -1) {
						v.push_back(j);
					}
				}
				int m = v.size();
				for(int j = 0; j < n; j++) {
					int num = 0;
					for(auto k : v) {
						if(f[k][j]) {
							num++;
						}	
					}
					if(num >= m / 2) {
						a[j] = id;	
					}
				}
				id++;
			}
		}
		for(int i = 0; i < n - 1; i++) {
			printf("%d ", a[i]);
		}
		printf("%d\n", a[n - 1]);
	}
}

你可能感兴趣的:(牛客多校,程序设计)