CF1598C Delete Two Elements


https://codeforces.com/contest/1598/problem/C
定義一個數組 \(\{a_i\}\)\(mean\)\(\frac{\sum{a_i}}{n}\),給定一個數組,問有多少個有序對 \((i,j), i\leq j\),使得去掉 \(a_i, a_j\)后數組的 \(mean' = mean\)

這題題面有毒,一開始理解成了數組的 \(gcd\) 不變,而且除法是數學除法,帶余數的那種

在理解了正確題意下來考慮這道題:
假設原數組的和為 \(sum\) ,原數組的 \(mean\)\(k\),那么一定有 \(nk = sum\)
現在去掉兩個數,數組的和變為 \((n-2)k\),因此被減去的兩數之和為 \(2sum/n\),顯然如果 \(2sum \mod n != 0\) 則不存在解。
接下來就可以枚舉 \(a_i+a_j\) 的數對個數,題解說這是一個經典問題,可以用 map 保存每個值出現了多少次,則對於值 \(a,\ 2sum/n-a\) 對答案的貢獻即為 \(cnt[a]*\ cnt[2sum/n-a]\), 如果 \(a,\ 2sum/n-a\) 兩值相等,那么答案需要--,最后再去重除2即可。

點擊查看代碼
#include <bits/stdc++.h>
using namespace std;

using DB = double;
using ll = long long;
using PII = pair<int, int>;
const int N = 2e5 + 10;
const ll INF = 1e18;
#define endl '\n'

int n = 2, m;
int a[N];

int st[6][1005], cntt[6];
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        ll sum = 0;
        map<int, int> cnt;
        for (int i = 0, x; i < n; i++) {
            cin >> a[i];
            sum += a[i];
            cnt[a[i]]++;
        }

        if (2 * sum % n != 0) {
            cout << 0 << endl;
            continue;
        }
        ll res = 2 * sum / n, ans = 0;
        for (int i = 0; i < n; i++) {
            int x = a[i];
            int y = res - x;
            ans += cnt[y];
            if (x == y)
                ans--;
        }

        cout << ans / 2 << endl;
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM