zoukankan      html  css  js  c++  java
  • [Luogu3936]Coloring

    Luogu

    sol

    模拟退火呀
    初始状态按顺序涂色,让同种颜色尽量放在一起。
    每次随机交换两个位置,注意(Delta)的计算
    瞎JB调一下参数就行了
    可以多做几次避免陷入局部最优解

    code

    #include<cstdio>
    #include<algorithm>
    #include<ctime>
    #include<cmath>
    using namespace std;
    const int N = 100;
    struct node{int a[25][25],tot;}ans;
    int n,m,c,p[N],dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
    double Rand(){return rand()%1000/1000.0;}
    bool inside(int x,int y){return 1<=x&&x<=n&&1<=y&&y<=m;}
    void SA(double T)
    {
        node now=ans,nw;
        int x1,y1,x2,y2,d;
        while (T>1e-15)
        {
            nw=now;
            x1=1+rand()%n,y1=1+rand()%m;
            x2=1+rand()%n,y2=1+rand()%m;
            if (x1==x2&&y1==y2) continue;
            for (int d=0;d<4;d++)
                if (inside(x1+dx[d],y1+dy[d]))
                    nw.tot-=(nw.a[x1][y1]!=nw.a[x1+dx[d]][y1+dy[d]]);
            for (int d=0;d<4;d++)
                if (inside(x2+dx[d],y2+dy[d]))
                    nw.tot-=(nw.a[x2][y2]!=nw.a[x2+dx[d]][y2+dy[d]]);
            swap(nw.a[x1][y1],nw.a[x2][y2]);
            for (int d=0;d<4;d++)
                if (inside(x1+dx[d],y1+dy[d]))
                    nw.tot+=(nw.a[x1][y1]!=nw.a[x1+dx[d]][y1+dy[d]]);
            for (int d=0;d<4;d++)
                if (inside(x2+dx[d],y2+dy[d]))
                    nw.tot+=(nw.a[x2][y2]!=nw.a[x2+dx[d]][y2+dy[d]]);
            if (nw.tot<=now.tot||exp((now.tot-nw.tot)/T)>Rand()) now=nw;
            if (nw.tot<ans.tot) ans=nw;
            T*=0.99999;
        }
    }
    int main()
    {
        scanf("%d %d %d",&n,&m,&c);
        for (int i=1;i<=c;++i) scanf("%d",&p[i]);
        for (int i=1,k=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                ans.a[i][j]=p[k]?k:++k,--p[k];
        for (int i=1;i<=n;++i)
            for (int j=1;j<=m;++j)
            {
                if (i<n&&ans.a[i][j]!=ans.a[i+1][j]) ++ans.tot;
                if (j<m&&ans.a[i][j]!=ans.a[i][j+1]) ++ans.tot;
            }
        SA(1);SA(1);SA(1);
        for (int i=1;i<=n;++i,puts(""))
            for (int j=1;j<=m;++j)
                printf("%d ",ans.a[i][j]);
        return 0;
    }
    
  • 相关阅读:
    Javascript对象原型prototype和继承
    Javascript(js)使用function定义构造函数
    phpExcel中文帮助手册
    php curl_init函数用法
    nginx启动,重启,关闭命令
    Nginx配置文件详细说明
    Nginx 简单的负载均衡配置示例
    MySQL数据库的同步配置
    ucenter home 视频增加缩略图
    web分词程序和算法
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8424060.html
Copyright © 2011-2022 走看看