• Luogu3936 Coloring(模拟退火)


      裸退火,每次交换两个格子即可。依旧不会调参,稍微抄了点参数并且把随机种子设成了一个神奇的数字终于过掉了

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    #define ll long long
    #define N 22
    #define M 55
    #define T0 1
    #define T1 1E-14
    #define delta 0.9999
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,c,a[M],color[N][N],cnt,ans,goal[N][N];
    int wx[4]={1,0,0,-1},wy[4]={0,1,-1,0};
    int calc(int x,int y)
    {
        int t=0;
        for (int k=0;k<4;k++)
        if (x+wx[k]>=1&&x+wx[k]<=n&&y+wy[k]>=1&&y+wy[k]<=m)
            if (color[x][y]!=color[x+wx[k]][y+wy[k]]) t++;
        return t;
    }
    void anneal()
    {
        double T=T0;
        while (T>T1)
        {
            int x1=rand()%n+1,y1=rand()%m+1,x2=rand()%n+1,y2=rand()%m+1;
            while (x1==x2||y1==y2) x1=rand()%n+1,y1=rand()%m+1,x2=rand()%n+1,y2=rand()%m+1;
            int d=0;
            d-=calc(x1,y1),d-=calc(x2,y2);
            swap(color[x1][y1],color[x2][y2]);
            d+=calc(x1,y1),d+=calc(x2,y2);
            if (d<0||rand()<exp(-d/T)*RAND_MAX) cnt+=d;
            else swap(color[x1][y1],color[x2][y2]);
            if (cnt<ans) ans=cnt,memcpy(goal,color,sizeof(color));
            T*=delta;
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("color.in","r",stdin);
        freopen("color.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),c=read();
        srand(20020509);
        for (int i=1;i<=c;i++) a[i]=read();
        int x=1,y=1;
        for (int i=1;i<=c;i++)
        while (a[i])
        {
            color[x][y]=i;
            a[i]--;y++;
            if (y>m) x++,y=1;
        }
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                for (int k=0;k<4;k++)
                if (i+wx[k]>=1&&i+wx[k]<=n&&j+wy[k]>=1&&j+wy[k]<=m)
                    if (color[i][j]!=color[i+wx[k]][j+wy[k]]) cnt++;
        ans=cnt>>=1;
        memcpy(goal,color,sizeof(color));
        for (int i=1;i<=20;i++) anneal();
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=m;j++)
            cout<<goal[i][j]<<' ';
            cout<<endl;
        }
        return 0;
    }
  • 相关阅读:
    软件架构师是如何工作
    安装flume由于HBASE出现的错误
    学习记录(Python集合)
    bzoj4199: [Noi2015]品酒大会
    清橙A1484
    codeforces 232D Fence
    bzoj2337: [HNOI2011]XOR和路径
    bzoj3143: [Hnoi2013]游走
    codeforces 235 B. Let's Play Osu!
    bestcoder单调区间
  • 原文地址:https://www.cnblogs.com/Gloid/p/9940811.html
Copyright © 2020-2023  润新知