社区讨论

MnZn模拟退火0pts求条

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

讨论操作

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

当前回复
4 条
当前快照
1 份
快照标识符
@miejgqep
此快照首次捕获于
2025/11/25 20:15
3 个月前
此快照最后确认于
2025/11/25 20:55
3 个月前
查看原帖
如题,样例过了,讨论区的hack也过了
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=33;
const double MX=1e6;
int T,n;
double a[N][2],s[2];
double rnd(double l,double r)
{
    return (double)rand()/RAND_MAX*(r-l)+l;
}
signed main()
{
    srand(time(NULL));
    cin>>T;
    while(T--)
    {
        cin>>n;
        s[0]=s[1]=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            a[(i+1)/2][i%2]=x;
            s[i%2]+=x;
        }
        int ans=1e18+10;
        int s1=s[0],s2=s[1];
        for(int i=1;i<=40;i++)
        {
            for(double t=MX;t>=1e-4;t*=0.999)
            {
                int x=rnd(1,(n+1)/2+1),y=rnd(1,(n+1)/2+1);
                int c1=s1+a[y][1]-a[x][0],c2=s2+a[x][0]-a[y][1];
                //cout<<x<<" "<<y<<"\n";
                if(abs(s1-s2)>abs(c1-c2)||exp((double)((s1-s2)-(c1-c2))/t)>rnd(0,1))
                {
                    //cout<<t<<"\n";
                    s1=c1,s2=c2;
                    swap(a[x][0],a[y][1]);
                }
                ans=min(ans,abs(s1-s2));
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

回复

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

正在加载回复...