列表

详情


NC22563. 最小相似度

描述

定义两个位数相等的二进制串的相似度
,所以
给定个长度为的二进制串
现在的问题是找出一个额外的长度为的二进制字符串,使得最小。
因为满足条件的可能不止一个,不需要输出串,只需要输出这个最小值即可。

输入描述

第一行两个整数
然后行,每行一个长度为的字符串

输出描述

输出一行一个整数表示答案--的最小值。

示例1

输入:

3 5
01001
11100
10111

输出:

2

说明:

只有当\ T=00010\ max \{ \text SIM(S_{1},T),SIM(S_{2},T)...SIM(S_{N},T) \}达到最小,为2,所以答案是2

示例2

输入:

1 8
10011000

输出:

0

说明:

只有当\ T=01100111\ max \{ \text SIM(S_{1},T),SIM(S_{2},T)...SIM(S_{N},T) \}达到最小,为0,所以答案是0

示例3

输入:

5 2
10
01
00
10
11

输出:

2

说明:

无论\ T=00、01、10、11中的任何一个,\ max \{ \text SIM(S_{1},T),SIM(S_{2},T)...SIM(S_{N},T) \}都为2,所以答案是2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 166ms, 内存消耗: 18792K, 提交时间: 2019-03-04 20:26:53

#include<bits/stdc++.h>
using namespace std;
int dp[1<<22];
int main(){
	char s[30];
	int n,m,ans=0;
	queue<int>q;
	memset(dp,-1,sizeof(dp));
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%s",s);
		int f=0;
		for(int j=0;j<m;j++)
			f+=(1<<j)*(s[j]-'0');
		if(dp[f]==-1){
			dp[f]=0;
			q.push(f);
		}
	} 
	while(!q.empty()){
		int u=q.front();
		q.pop();
		ans=max(ans,dp[u]);
		for(int i=0;i<m;i++){
			if(dp[u^(1<<i)]==-1){
				dp[u^(1<<i)]=dp[u]+1;
				q.push(u^(1<<i));
			}
		}
	}
	printf("%d\n",m-ans);
}

C++11(clang++ 3.9) 解法, 执行用时: 167ms, 内存消耗: 10476K, 提交时间: 2020-02-27 12:52:41

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,i,now,j,d[2000001];
char s[1001];
queue<int>q;
int main()
{
	scanf("%d%d",&n,&m);
	memset(d,-1,sizeof(d));
	for(i=1;i<=n;i++)
	{
		scanf("%s",s);
		now=0;
		for(j=0;j<m;j++)
		now=now*2+s[j]-'0';
		q.push(now);
		d[now]=0;
	}
	while(q.size())
	{
		now=q.front();q.pop();
		ans=max(ans,d[now]);
		for(i=0;i<m;i++)
		if(d[now^(1<<i)]==-1)
		{
			d[now^(1<<i)]=d[now]+1;
			q.push(now^(1<<i));
		}
	}
	printf("%d",m-ans);
}

上一题