散列表
数组模拟
- M M M代表散列表的长度,应设定为大于数据规模 N N N的一个质数
- 在开始需将
h
h
h初始化为正无穷(
0x3f3f3f3f
)或-1
,具体题目具体看
static int N = 100010;
static int M = 999997;
static int[] h = new int[M];
static int find(int x) { // 返回x在散列表中的key
int t = (x % M + M) % M;
while (h[t] != INF && h[t] != x) {
t ++;
if (t == M) {
t = 0;
}
}
return t;
}
static void insert(int x) {
int t = find(x);
h[t] = x;
}
static boolean query(int x) {
int t = find(x);
if (h[t] == x) {
return true;
}
return false;
}
例题
注意:
- 该方法不是本题的唯一方法
- 二分也能做,样例能不能全过不确定(大部分是没问题的)
- 相关代码放在最后,有兴趣可以看看
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static class Sum {
int s, c, d;
public Sum(int s, int c, int d) {
this.s = s;
this.c = c;
this.d = d;
}
}
static Scanner in = new Scanner(System.in);
static int N = 5000010, M = 10000007;
static int n;
static Sum[] sum = new Sum[N];
// id存储的是在相同s下,[c, d]字典序最小的key对应的记录在sum中的索引
static int[] h = new int[M], id = new int[M];
static int sqr(int x) {
return x * x;
}
static int find(int x) {
int t = (x % M + M) % M;
while (h[t] != -1 && h[t] != x) {
t ++;
if (t == M) {
t = 0;
}
}
return t;
}
static boolean compare(int c1, int d1, int c2, int d2) {
long s1 = (long) c1 * N + d1;
long s2 = (long) c2 * N + d2;
return s1 <= s2;
}
public static void main(String[] args) {
n = in.nextInt();
Arrays.fill(h, -1);
int m = 0;
for (int c = 0; sqr(c) <= n; c ++) {
for (int d = c; sqr(c) + sqr(d) <= n; d ++) {
int s = sqr(c) + sqr(d);
sum[++ m] = new Sum(s, c, d);
int t = find(s);
if (h[t] == -1) {
h[t] = s;
}
if (id[t] == 0 || compare(c, d, sum[id[t]].c, sum[id[t]].d)) {
id[t] = m;
}
}
}
for (int a = 0; sqr(a) <= n; a ++) {
for (int b = 0; sqr(a) + sqr(b) <= n; b ++) {
int s = n - sqr(a) - sqr(b);
int t = find(s);
if (h[t] == s) {
int c = sum[id[t]].c, d = sum[id[t]].d;
System.out.printf("%d %d %d %d\n", a, b, c, d);
return;
}
}
}
}
}
附录
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static class Pair implements Comparable<Pair>{
int s, c, d;
public Pair(int s, int c, int d) {
this.s = s;
this.c = c;
this.d = d;
}
@Override
public int compareTo(Main.Pair o) {
if (this.s != o.s) {
return this.s - o.s;
}
if (this.c != o.c) {
return this.c - o.c;
}
return this.d - o.d;
}
}
static Scanner in = new Scanner(System.in);
static int N = 2500010;
static int n;
static Pair[] p = new Pair[N];
public static void main(String[] args) {
n = in.nextInt();
int idx = 0;
for (int c = 0; c * c <= n; c ++) {
for (int d = c; c * c + d * d <= n; d ++) {
int t = c * c + d * d;
p[idx ++] = new Pair(t, c, d);
}
}
Arrays.sort(p, 0, idx);
for (int a = 0; a * a <= n; a ++) {
for (int b = a; a * a + b * b <= n; b ++) {
int t = n - (a * a + b * b);
int l = 0, r = idx - 1;
while (l < r) {
int mid = l + r >> 1;
if (p[mid].s >= t) {
r = mid;
} else {
l = mid + 1;
}
}
if (a * a + b * b + p[l].s == n) {
System.out.printf("%d %d %d %d\n", a, b, p[l].c, p[l].d);
return;
}
}
}
}
}