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