【JZOJ3231】海明距离

description

对于二进制串a,b,他们之间的海明距离是指两个串异或之后串中1的个数。异或的规则为:

0 XOR 0 = 0

1 XOR 0 = 1

0 XOR 1 = 1

1 XOR 1 = 0

计算两个串之间的海明距离的时候,他们的长度必须相同。现在我们给出N个不同的二进制串,请计算出这些串两两之间的最短海明距离。


analysis

  • 欺诈题

  • 可以知道 500 ∗ 500 500*500 500500循环,答案大于 3 3 3的几率小于 1 1 0 24 1\over{10^{24}} 10241

  • 数据根本构造不出来,于是水法就可以解决


code

#include
#include
#include
#define MAXN 100005
#define INF 1000000007
#define ll long long
#define fo(i,a,b) for (ll i=a;i<=b;++i)
#define fd(i,a,b) for (ll i=a;i>=b;--i)

using namespace std;

ll a[20][20],f[MAXN][7];
ll turn[205];
ll n,T,mn;

inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
inline ll min(ll x,ll y){return x<y?x:y;}
int main()
{
	T=read();
	for (char ch='0';ch<='9';++ch)turn[ch]=ch-'0';
	turn['A']=10,turn['B']=11,turn['C']=12,
	turn['D']=13,turn['E']=14,turn['F']=15;
	fo(i,0,15)
	{
		fo(j,i+1,15)
		{
			ll k=i^j;
			while (k){if (k&1)++a[i][j];k>>=1;}
			a[j][i]=a[i][j];
		}
	}
	while (T--)
	{
		n=read(),mn=INF,scanf("\n");
		fo(i,1,n)
		{
			fo(j,1,5)f[i][j]=turn[getchar()];
			scanf("\n");
		}
		fo(i,1,min(n,400))
		{
			fo(j,i+1,min(n,400))
			{
				ll tot=0;
				fo(k,1,5)tot+=a[f[i][k]][f[j][k]];
				mn=min(mn,tot);
			}
		}
		printf("%lld\n",mn);
	}
	return 0;
}

你可能感兴趣的:(水法,模拟赛)