我一直在尝试在 ACM Timus 上解决这个问题
http://acm.timus.ru/problem.aspx?space=1&num=1932
我的第一种方法是 O(n^2) 肯定不够快,无法通过所有测试。下面的 O(n^2) 代码在测试 10 中给出了 TL。
import java.util.*;
import java.io.*;
public class testtest
{
public static void main(String[] args) throws IOException
{
BufferedReader rr = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(rr.readLine());
String[] p = new String[n];
for (int i = 0; i < n; i ++)
{
p[i] = rr.readLine();
}
int[] diff = new int[]{0, 0, 0, 0};
for (int i = 0; i < n - 1; i ++)
{
for (int j = i + 1; j < n; j ++)
{
int ans = (p[i].charAt(0) == p[j].charAt(0) ? 0 : 1) +
(p[i].charAt(1) == p[j].charAt(1) ? 0 : 1) +
(p[i].charAt(2) == p[j].charAt(2) ? 0 : 1) +
(p[i].charAt(3) == p[j].charAt(3) ? 0 : 1);
diff[ans - 1] ++;
}
}
System.out.print(diff[0] + " " + diff[1] + " " + diff[2] + " " + diff[3]);
}
}
有什么想法可以使这种方法更快吗?我注意到输入中只允许有限的一组字符('0' .. '9', 'a' .. 'f')所以我们可以创建数组(内存限制就足够了)来快速检查是否之前输入过的字符。
谢谢...我不需要实际的实施,只需快速的想法/想法就可以了。 编辑:感谢伟大的想法。我已经尝试使用位逻辑对 O(n^2) 进行改进,但仍然超出了时间限制。帕斯卡代码如下。
program Project2;
{$APPTYPE CONSOLE}
var
i, j, n, k, bits: integer;
arr: array[1..65536] of integer;
diff: array[1..4] of integer;
a, b, c, d: char;
function g(c: char): integer; inline;
begin
if ((c >= '0') and (c <= '9')) then
begin
Result := Ord(c) - 48;
end
else
begin
Result := Ord(c) - 87;
end;
end;
begin
Readln(n);
for i := 1 to n do
begin
Read(a); Read(b); Read(c); Readln(d);
arr[i] := g(a) * 16 * 16 * 16 + g(b) * 16 * 16 + g(c) * 16 + g(d);
for j := 1 to i - 1 do
begin
bits := arr[i] xor arr[j];
k := ((bits or (bits shr 1) or (bits shr 2) or (bits shr 3)) and $1111) mod 15;
Inc(diff[k]);
end;
end;
Write(diff[1], ' ', diff[2], ' ', diff[3], ' ', diff[4]);
{$IFNDEF ONLINE_JUDGE}
Readln;
{$ENDIF}
end.
所以我想,我必须尝试其他更好的建议..
编辑: 我已经尝试过 Daniel 的算法,它非常有前途,也许下面的代码有错误,在测试 10 中不断得到错误的答案......有人可以看看吗?非常感谢...
import java.util.*;
import java.io.*;
public class testtest
{
private static int g(char ch)
{
if ((ch >= '0') && (ch <= '9'))
{
return (int)ch - 48;
}
return (int)ch - 87;
}
public static void main(String[] args) throws IOException
{
BufferedReader rr = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(rr.readLine());
int[] p = new int[n];
int[] all = new int[65536];
int[][] miss = new int[4][4096];
int[] g12 = new int[256];
int[] g13 = new int[256];
int[] g14 = new int[256];
int[] g23 = new int[256];
int[] g24 = new int[256];
int[] g34 = new int[256];
int[][] gg = new int[4][16];
int same3, same2, same1, same0, same4;
for (int i = 0; i < n; i ++)
{
String s = rr.readLine();
int x = g(s.charAt(0)) * 4096 + g(s.charAt(1)) * 256 + g(s.charAt(2)) * 16 + g(s.charAt(3));
p[i] = x;
all[x] ++;
miss[0][x >> 4] ++;
miss[1][(x & 0x000F) | ((x & 0xFF00) >> 4)] ++;
miss[2][(x & 0x00FF) | ((x & 0xF000) >> 4)] ++;
miss[3][x & 0x0FFF] ++;
g12[x >> 8] ++;
g13[((x & 0x00F0) >> 4) | ((x & 0xF000) >> 8)] ++;
g14[(x & 0x000F) | ((x & 0xF000) >> 8)] ++;
g23[(x & 0x0FF0) >> 4] ++;
g24[(x & 0x000F) | ((x & 0x0F00) >> 4)] ++;
g34[x & 0x00FF] ++;
gg[0][x >> 12] ++;
gg[1][(x & 0xF00) >> 8] ++;
gg[2][(x & 0xF0) >> 4] ++;
gg[3][x & 0xF] ++;
}
same4 = 0;
for (int i = 0; i < 65536; i ++)
{
same4 += (all[i] - 1) * (all[i]) / 2;
}
same3 = 0;
for (int i = 0; i < 4096; i ++)
{
same3 += (miss[0][i] - 1) * (miss[0][i]) / 2;
same3 += (miss[1][i] - 1) * (miss[1][i]) / 2;
same3 += (miss[2][i] - 1) * (miss[2][i]) / 2;
same3 += (miss[3][i] - 1) * (miss[3][i]) / 2;
}
same2 = 0;
for (int i = 0; i < 256; i ++)
{
same2 += (g12[i] - 1) * g12[i] / 2;
same2 += (g13[i] - 1) * g13[i] / 2;
same2 += (g14[i] - 1) * g14[i] / 2;
same2 += (g23[i] - 1) * g23[i] / 2;
same2 += (g24[i] - 1) * g24[i] / 2;
same2 += (g34[i] - 1) * g34[i] / 2;
}
same1 = 0;
for (int i = 0; i < 16; i ++)
{
same1 += (gg[0][i] - 1) * gg[0][i] / 2;
same1 += (gg[1][i] - 1) * gg[1][i] / 2;
same1 += (gg[2][i] - 1) * gg[2][i] / 2;
same1 += (gg[3][i] - 1) * gg[3][i] / 2;
}
same3 -= 4 * same4;
same2 -= 6 * same4 + 3 * same3;
same1 -= 4 * same4 + 3 * same3 + 2 * same2;
same0 = (int)((long)(n * (n - 1) / 2) - same4 - same3 - same2 - same1);
System.out.print(same3 + " " + same2 + " " + same1 + " " + same0);
}
}
编辑 终于得到了交流...感谢丹尼尔如此出色的算法!