Codeforces 670C (離散化入門題)
阿新 • • 發佈:2020-08-08
原題連結:https://codeforces.com/problemset/problem/670/C
題目大意:
有 n 個人,每人會且僅會一種語言. (n ≤ 2e5)
語言有各自的編號(≤ 1e9)
這些人去看電影,一共有 m 種電影. (m ≤ 2e5)
每個電影的聲音與字幕語言都不一樣.
若有人的語言與聲音語言一樣,則稱這個人很高興♂.
若有人的語言與字幕語言一樣,則稱這個人比較高興.
現讓你選擇一場電影,使得此電影中,很高興的人最多,在此條件下,再使比較高興的人最多.
分析:
因為要統計每種語言的人數,而語言編號 ≤ 1e9,存不下.
所以考慮離散化.
可得離散化之後,語言總數最多 n + 2m 種.
AC程式碼:
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; const int maxn = 2e5 + 5; int n, m; int a[maxn], b[maxn], c[maxn]; int sum[maxn * 3]; int cnt, mm; int arr[maxn * 3], num[maxn * 3]; void discrete() {//離散化 sort(arr + 1, arr + cnt + 1); for (int i = 1; i <= cnt; i++) { if (i == 1 || arr[i] != arr[i - 1]) num[++mm] = arr[i]; } } int query(int x) {//二分查詢x的位置 return lower_bound(num + 1, num + mm + 1, x) - num; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) {//將所有電影和人涉及的語言放進一個數組,排序並離散化 scanf("%d", &a[i]); arr[++cnt] = a[i]; } scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d", &b[i]); arr[++cnt] = b[i]; } for (int i = 1; i <= m; i++) { scanf("%d", &c[i]); arr[++cnt] = c[i]; } discrete();//離散化 for (int i = 1; i <= n; i++) { int id = query(a[i]);//統計每種語言的人的數量 ++sum[id]; } int bmax = -1, cmax = -1, ans = 0; for (int i = 1; i <= m; i++) {//選擇滿足題目要求的電影 int x = query(b[i]); int y = query(c[i]); if (sum[x] > bmax) {//優先考慮讓很高興的人最多 bmax = sum[x], cmax = sum[y]; ans = i; } else { if (sum[x] == bmax && sum[y] > cmax) {//如果答案不唯一、則在此前提下再讓比較高興的人最多 bmax = sum[x], cmax = sum[y]; ans = i; } } } printf("%d\n", ans); return 0; }
暴力解法:670ms
#include<bits/stdc++.h> using namespace std; typedef pair<int, int>PII; int n, m; int a[20000005]; map<int, int>mp; int main() { //freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0); cin >> n; for (int i = 1, a; i <= n; ++i) cin >> a, mp[a]++; int k, max1 = -1, max2 = -1; cin >> m; for (int i = 1; i <= m; ++i) { cin >> a[i]; max1 = max(max1, mp[a[i]]); } for (int i = 1,b; i <= m; ++i) { cin >> b; if (mp[a[i]] == max1 && mp[b] > max2) max2 = mp[b], k = i; } cout << k << endl; }