1. 程式人生 > 實用技巧 >Codeforces 670C (離散化入門題)

Codeforces 670C (離散化入門題)

原題連結: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;
}