【佛山市选2013】海明距离
Description
对于二进制串a,b,他们之间的海明距离是指两个串异或之后串中1的个数。异或的规则为:
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0
计算两个串之间的海明距离的时候,他们的长度必须相同。现在我们给出N个不同的二进制串,请计算出这些串两两之间的最短海明距离。
Input
第一个数字是整数T(T≤10),代表数据的组数。
接下来有T组数据,每组数据的第一行是一个正整数N,代表不同的二进制串的个数。接下来是N行,每行都是一个二进制串(长度是5)。我们用数字(0-9)和字符(A-F)来表示这个二进制串。它代表这个二进制串的16进制码。例如,“12345”代表的二进制串为“00010010001101000101”。
Output
对于每个数据,请输出一个整数,即答案值。
Sample Input
2
2
12345
54321
4
12345
6789A
BCDEF
0137F
Sample Output
6
7
反思&题解
比赛思路: 暴力……
正解思路: 01trie可以轻松过,但是有个大大大大大大大大大……水法,直接取前1000个两两异或统计答案就可以过了,本人亲测有效。(好像用组合数是可以证明卡这个方法很难的,而且不管怎么卡再打几个特判也还是可以过)
反思: 突然感觉位运算的题好像都那么多可以水的???
CODE
var
t,n,i,j,tot,tt,k,sum,num,ans:longint;
a:array[0..100005]of longint;
s:string;
function power(x,y:longint):longint;
var
tot:longint;
begin
tot:=1;
while y>0 do
begin
if (y and 1)=1 then tot:=tot*x;
y:=y>>1;
x:=x*x;
end;
exit(tot);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
begin
readln(t);
while t>0 do
begin
readln(n);
tot:=0;
fillchar(a,sizeof(a),0);
for i:=1 to n do
begin
readln(s);
for j:=1 to 5 do
begin
if (s[j]>='0')and(s[j]<='9') then tt:=ord(s[j])-48
else tt:=ord(s[j])-55;
a[i]:=a[i]+tt*power(16,5-j);
end;
end;
ans:=12345678;
for i:=1 to min(1000,n)-1 do
begin
for j:=i+1 to min(1000,n) do
begin
sum:=a[i] xor a[j];
num:=0;
for k:=0 to 19 do
begin
if (sum and (1<<k))>0 then inc(num);
end;
ans:=min(ans,num);
end;
end;
writeln(ans);
dec(t);
end;
end.