計蒜客 成績統計 (Hash表)
阿新 • • 發佈:2017-11-28
就是 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表)