散列表-数组模拟

散列表

数组模拟

  • 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;
}

例题

蓝桥杯 2016 省 AB] 四平方和 - 洛谷

注意:

  • 该方法不是本题的唯一方法
  • 二分也能做,样例能不能全过不确定(大部分是没问题的)
    • 相关代码放在最后,有兴趣可以看看
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;
                }
            }
        }
    }
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值