加载中...

手写哈希表bool find(int x)

开放寻址法

int find(int x){
  int t =(x % N + N) % N;/正数负数都存到里面 找个位置给他
  while(h[t] != null && h[t] != x){//如果这个位置有值 但是不是那个位置 就找下个位置
     t++;
     if(t==N) t=0;//到了尽头回去
  }
  return t;
}
LL find(int x,int t){//哈希记录两个值
  LL key = r * 100ll + t;/正数负数都存到里面 找个位置给他 
  int k = key % M; 
  while(h[key] != -1 && h[K] != key){//如果这个位置有值 但是不是那个位置 就找下个位置
     if( ++ k == M ) k=0;//到了尽头回去
  }
  if(h[k]== -1) h[k]=key ,cnt[k]=0;
  
  return k;//找到了
}

https://www.acwing.com/problem/content/4614/

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;
const int N = 200010, M = 10000007;

int n, m;
int a[N];
LL h[M];
int cnt[M];

int find(int r, int t)
{
    LL key = r * 100ll + t;//拼接
    int k = key % M;
    while (h[k] != -1 && h[k] != key)
        if ( ++ k == M)
            k = 0;
    if (h[k] == -1) h[k] = key, cnt[k] = 0;
    return k;
}

LL work()
{
    LL res = 0;
    memset(h, -1, sizeof h);
    for (int i = 0; i < n; i ++ )
    {
        int r = a[i] % m;//-a[i]的余数
        if (r) r = m - r;
        int t = 0, x = a[i];
        while (x) t ++, x /= 10;
        res += cnt[find(r, t)];//找到那个数

        for (int j = 1, x = 10; j <= 10; j ++, x = x * 10ll % m)
            cnt[find((LL)a[i] * x % m, j)] ++ ;//存对于ai每个数 * k次10的结果
    }
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);

    LL res = work();//从左往右 求 然后reverse 再求一遍
    reverse(a, a + n);
    res += work();

    printf("%lld\n", res);

    return 0;
}

posted @ 2022-09-06 20:41  liang302  阅读(43)  评论(0编辑  收藏  举报