Deltix Round, Spring 2021

群里都说这场是诈骗场,不太懂的样子qwq

还是先开的 C,开始猜题面,照着样例似乎没啥问题直接写了,\(n^2\) 就可以过了qwq

B

一如既往的不会 B ,后来发现操作与给的数组可以无关就很好做了……

A

很简单呀,找两边离得近的,看距离是否一样和能否覆盖到即可。

但是FST了,因为inf不够大。

D

场上没想出来,看到每次随机选一个有不小于 50% 的概率得到答案,随机选择 50 次就可以了。然后每次把 n 个数压成不大于 p 的二进制,再dp就可以了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>

using namespace std;

const int N=2e5+7;
char s[100];
int a[N][66],n,m,p;
int buc[40000],dp[40000],f[40000];

int ans=0,num[66],arr[N];

void print(int cnt,int x)
{
	for(int i = cnt;i >= 1;i --) printf("%d",!!(x&(1<<i>>1)));
	return ;
}

int myrand()
{
	return rand()+rand()*65536;
}

void calc(int x)
{
	int tmp[20],cnt=0;
	memset(tmp,0,sizeof(tmp));memset(buc,0,sizeof(buc));
	for(int i = 1;i <= m;i ++) if(a[x][i]) tmp[++cnt] = i;
	for(int i = 1;i <= n;i ++) {
		int o = 0;
		for(int j = 1;j <= cnt;j ++) {
			o <<= 1;
			if(a[i][tmp[j]]) o |= 1;
		}
		buc[o] ++;
	}
	memset(dp,0,sizeof(dp));
	for(int i = 0;i < (1<<cnt);i ++) {
		for(int j = i;j;j = (j-1)&i) {
			dp[j] += buc[i];
		}
	}
	int o = 0;
	for(int i = 1;i < (1<<cnt);i ++) {
		if(dp[i] >= (n+1)/2 && f[i] > f[o]) o = i;
	}
	if(f[o] <= ans) return;
	memset(num,0,sizeof(num));ans = f[o];
	for(int i = 1;i <= cnt;i ++) {
		if((1<<i>>1)&o) num[tmp[cnt-i+1]] = 1;
	}
}

int main()
{
	scanf("%d %d %d",&n,&m,&p);
	for(int i = 1;i <= n;i ++) {
		scanf("%s",s+1);
		for(int j = 1;j <= m;j ++) a[i][j] = s[j]-'0';
	}
	for(int i = 1;i < (1<<p);i ++) f[i] = f[i-(i&-i)] + 1;
	srand(time(0));
	for(int i = 1;i <= 100;i ++) {
		int t = myrand()%n+1;
		calc(t);
	}
	for(int i = 1;i <= m;i ++) printf("%d",num[i]);
	return 0;
}
posted @ 2021-05-31 19:00  nao-nao  阅读(73)  评论(0编辑  收藏  举报