Hash (POJ 2785)

這兩天看文章,看得手又癢了。於是提前開了自己掛的hash專題。因爲在數據結構課上有學過,所以大致思路還記得。看了下網上的解法和細節上的東西,差不多就能寫一些簡單題了。

這題用的是線性探測除法散列法,要注意的是key = (num % mod + mod) % mod。前面的%mod是爲了防止出現比mod大的數,再加mod是爲了解決負數的問題。

這題其實也可以用n^2+二分,但是題目給的內存很大,標程估計也是要用哈希的意思。

從virtual oj的提交記錄來看,基本二分的都在5000+MS,有一個hash的做法竟然用了10000+MS,看了下代碼,可能是指針的關係?

最後提交的代碼是3000+MS過的。

思路就是:用前兩列的和維護一個hash,然後用第三第四列的和的相反數去hash裏面找即可。


Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int mod = 15999991;
int hash[16000011]; //hash table
int cnt[16000011];  // time of the each hash relationship
int a[4444][4];
int n;

void make_hash(int num)
{
     int key = (num % mod + mod) % mod;  //division hash
     while((hash[key] != num) && (cnt[key] > 0))    key = (key + 1) % mod; //linear detect
     hash[key] = num;
     cnt[key] ++;
}

int get_num(int num)
{
    int key = (num % mod + mod) % mod;
    while((hash[key] != num) && (cnt[key] > 0))     key = (key + 1) % mod;
    return cnt[key];
}

int main()
{
    while(scanf("%d", &n) != EOF)
    {
                      int i, j, ans = 0;
                      memset(hash, 0, sizeof(hash));
                      memset(cnt, 0, sizeof(cnt));
                      for(i = 1; i <= n; i ++)
                            for(j = 0; j < 4; j ++)
                                  scanf("%d", &a[i][j]);
                      for(i = 1; i <= n; i ++)
                            for(j = 1; j <= n; j ++)
                                  make_hash(a[i][0] + a[j][1]);
                      for(i = 1; i <= n; i ++)
                            for(j = 1; j <= n; j ++)
                                  ans += get_num(-(a[i][2] + a[j][3]));
                      printf("%d\n", ans);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章