HDU 6237 A Simple Stone Game——贪心

版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82682559

首先将所有数的总和唯一分解,答案一定是某个素数,因为如果答案是合数的话肯定也可以是这个合数的素因子,这样只会多不会少。然后枚举素因子,对每个数构造一个与大于他的倍数的差值,然后按照这个差值从大到小贪心即是最优情况

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
const ll INF = 1e18;
int a[maxn];
ll p[100];
ll b[maxn];
int main() {
    int T, n;
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        ll sum = 0;
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]), sum += a[i];
        int cnt = 0;
        ll x = sum;
        for (ll i = 2; i * i <= x; i++) {
            if (x % i == 0) {
                p[++cnt] = i;
                while (x % i == 0) x /= i;
            }
        }
        if (x > 1) p[++cnt] = x;
        ll ans = INF;
        for (int i = 1; i <= cnt; i++) {
            ll need = sum / p[i];
            for (int j = 1; j <= n; j++) b[j] = (a[j]/p[i]+1)*p[i]-a[j], need -= a[j]/p[i];
            sort(b+1, b+1+n);
            ll res = 0;
            for (int j = 1; j <= n && need > 0; j++) res += b[j], need--;
            ans = min(ans, res);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/82682559