【JZOJ3231】海明距離

description

對於二進制串a,b,他們之間的海明距離是指兩個串異或之後串中1的個數。異或的規則爲:

0 XOR 0 = 0

1 XOR 0 = 1

0 XOR 1 = 1

1 XOR 1 = 0

計算兩個串之間的海明距離的時候,他們的長度必須相同。現在我們給出N個不同的二進制串,請計算出這些串兩兩之間的最短海明距離。


analysis

  • 欺詐題

  • 可以知道500500500*500循環,答案大於33的機率小於110241\over{10^{24}}

  • 數據根本構造不出來,於是水法就可以解決


code

#include<stdio.h>
#include<string.h>
#include<algorithm>
#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章