1. 程式人生 > >計蒜客 成績統計 (Hash表)

計蒜客 成績統計 (Hash表)

就是 space tdi string name esp turn std scan


鏈接 : Here!

思路 : 如果用 $STL$ 的 $map$ 或者是使用 $unordered\underline{}map$ 的話是會 $T$ 的, 所以得手寫一個 $hash表$. 其實這個題題意一開始看的話還是蠻難以理解的. 但是如果理解了題意, 這道題就非常簡單了.

題目樣例解析 : 小 $K$ 一共采訪了 $5$ 個同學, 他們反饋的結果是 $1, 1, 2, 2, 3$ . 那麽, 最優解為 $9$, 下面給出一個表, 表示最優解的詳細情況. 首先先給 $5$ 名同學編號 $1, 2, 3, 4, 5$ , $1$ 號同學和 $2$ 號同學都說有 $1$ 個人跟他們成績一樣, 因此可以把 $1,2$ 放到一個集合中, 發現滿足要求, 不需要添加新同學($+0$). $3$ 號同學和 $4$ 號同學都說有 $2$ 個人跟他們成績一樣, 因此可以把 $3, 4$ 放到一個集合中, 發現不滿足要求, 需要添加新同學($+1$). $5$ 號同學說有 $3$ 個人跟他成績一樣, 因此可以把 $5$ 放到一個集合中, 發現不滿足要求, 需要添加新同學($+3$). 因此答案就是 $5 + 0 + 1 + 3 = 9$


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

typedef long long ll;
const int MAX_N = 10000019;

ll _hash[MAX_N + 10] = {0}, _count[MAX_N + 10]; 
ll N, M;
ll _seed;

void insert_hash(ll x) {
    ll pos = (x % MAX_N);
    // 處理hash沖突, 如果模一個素數的話...應該很少遇到沖突
    while
(_hash[pos] != x && _hash[pos] != 0) { pos = pos + 1; pos %= MAX_N; } if (_hash[pos] == 0) { _hash[pos] = x; } ++_count[pos]; } int main() { scanf("%lld%lld", &N, &M); for (int i = 0 ; i * 100 < N ; ++i) { scanf("
%lld", &_seed); for (int j = 0 ; j < 100 ; ++j) { insert_hash(_seed + 1); _seed = (_seed * 109 + 107) % M; } } ll ans = 0; for (int i = 0 ; i < MAX_N ; ++i) { if (_hash[i] == 0) continue; ans += ((_count[i] % (_hash[i]) == 0) ? _count[i] : (ll)(_count[i] / (_hash[i]) + 1) * (ll)(_hash[i])); } printf("%lld\n", ans); return 0; }

計蒜客 成績統計 (Hash表)