社区讨论

为啥会T啊 60pts

P3878[TJOI2010] 分金币参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mdn2d4b9
此快照首次捕获于
2025/07/28 20:07
7 个月前
此快照最后确认于
2025/11/04 04:29
4 个月前
查看原帖
都放这么小了,还jb T
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e5 + 5;
int n; 
int v[N], sum;
int ans;
const double d = 0.9511;
int val()
{
    int _ = 0, cnt = 0;
    for(int i = 1;i <= n;i ++ ){
        _ += v[i]; cnt ++ ;
        if(abs(cnt - (n - cnt)) <= 1){
            return abs(_ - sum + _);
        }
    }
}
void SA()
{
    for(int i = 1;i <= n;i ++ ) swap(v[i], v[rand() % n + 1]);
    double T = 7000;
    int now = ans;
    while(T > 1e-10){
        int x = rand() % n + 1, y = rand() % n + 1;
        if(x == y) continue;
        swap(v[x], v[y]);
        int num = val(), diff = num - now;
        if(diff < 0){
            now = num;
            if(now < ans) ans = now;
        }
        else if(RAND_MAX * exp(-diff / T) <= rand()) swap(v[x], v[y]);
        T *= d;
    }
}
void work()
{
    srand(345322);
    cin >> n;
    sum = 0;
    for(int i = 1;i <= n;i ++ ){
        cin >> v[i]; sum += v[i];
    }
    ans = val();
    int N = 125;
    while(ans && N -- > 0) SA();
    cout << ans << endl;
}
signed main()
{
    int T;cin >> T; while(T -- ) work();
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...