首页 > 其他分享 >ABC347G题解

ABC347G题解

时间:2024-03-30 21:58:27浏览次数:20  
标签:10 int 题解 pos long rnd ABC347G now

我不会,但是我会退火!

第一眼,\(n\le 20\)。

退火,启动!

大致思路就是随机选一个初始为 0 的数置为 \(1\sim 5\) 中的某个数,显然图中没有 0 一定不比有 0 劣(把所有 0 改成同一个数一定不劣)。

然后把单次计算的复杂度从 \(O(n^2)\) 变成 \(O(1)\):更新有变化位置的值就行了。

瞎调调参数就有概率能过了,吃了 8 发。

自己赛时的参数是 \(k=0.99993,T_{start}=10^{10},T_{end}=10^{-15}\)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

using D = long double;

const int N = 25;
int a[N][N], b[N][N], ans = 1e9;
pair<int, int> pos[N * N];
int h, n;

mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());

inline int p2(int x) {return x * x;}

int calc(int r, int x, int y, int v)
{
    for(int i = max(x - 1, 1); i <= min(x, n); i ++)
    for(int j = max(y - 1, 1); j <= min(y, n - 1); j ++)
        r -= p2(a[i][j] - a[i][j + 1]);
    for(int i = max(x - 1, 1); i <= min(x, n - 1); i ++)
    for(int j = max(y - 1, 1); j <= min(y, n); j ++)
        r -= p2(a[i][j] - a[i + 1][j]);
    a[x][y] = v;
    for(int i = max(x - 1, 1); i <= min(x, n); i ++)
    for(int j = max(y - 1, 1); j <= min(y, n - 1); j ++)
        r += p2(a[i][j] - a[i][j + 1]);
    for(int i = max(x - 1, 1); i <= min(x, n - 1); i ++)
    for(int j = max(y - 1, 1); j <= min(y, n); j ++)
        r += p2(a[i][j] - a[i + 1][j]);
    return r;
}

int init()
{
    int tans = 0;
    for(int i = 1; i <= n; i ++)
    for(int j = 1; j < n; j ++)
        tans += p2(a[i][j] - a[i][j + 1]);
    for(int i = 1; i < n; i ++)
    for(int j = 1; j <= n; j ++)
        tans += p2(a[i][j] - a[i + 1][j]);
    return tans;
}

D rnd01() {return rnd() * 1.L / UINT_MAX;}

void SA()
{
    int res = ans; memcpy(a, b, sizeof a);
    D T = 1e10, ed = 1e-15, k = 0.99993;
    while(T > ed)
    {
        int u = rnd() % h + 1;
        int v = rnd() % 5 + 1;
        int v0 = a[pos[u].first][pos[u].second];
        int now = calc(res, pos[u].first, pos[u].second, v);
        if(now <= ans)
        {
            ans = res = now;
            memcpy(b, a, sizeof a);
        }
        else if(rnd01() < exp((res - now) / T)) res = now;
        else a[pos[u].first][pos[u].second] = v0;
        T *= k;
    }
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= n; j ++)
        {
            cin >> b[i][j];
            if(b[i][j] == 0) pos[++h] = {i, j}, b[i][j] = 1;
        }
    }
    memcpy(a, b, sizeof a);
    ans = init();
    // cerr << calc() << endl;
    if(h) while(clock() * 1000.0 / CLOCKS_PER_SEC < 1780) SA();
    cerr << ans;
    for(int i = 1; i <= n; i ++)
    for(int j = 1; j <= n; j ++)    
        cout << b[i][j] << " \n"[j == n];

    return 0;
}

标签:10,int,题解,pos,long,rnd,ABC347G,now
From: https://www.cnblogs.com/adam01/p/18106079

相关文章

  • P5624 [Celeste-A] Black Moonrise 题解
    考虑莫队。记数\(i\)的个数为\(c_i\),套路地用莫比乌斯函数容斥,发现答案为\(\sum_{i=1}^{10^5}\frac{c_i(c_i+1)}2\sum_{d|i}\mu(\fracid)d\)。先预处理出前面的常数和每个数的因子,每次移动端点枚举因子更新答案即可。因为数是随机的,所以时间复杂度\(\mathcalO(n\sqrtn......
  • 信息工程大学第五届超越杯程序设计竞赛(同步赛)题解
    比赛传送门c++模板框架#pragmaGCCoptimize(3,"Ofast","inline")#include<bits/stdc++.h>#definerep(i,a,b)for(inti=a;i<b;++i)#defineper(i,a,b)for(inti=a;i>b;--i)#definesesecond#definefifirst#defineendl'\n�......
  • luogu P1543 [POI2004] SZP 题解
    题目传送门前置知识树形DP解法将\(a_{i}\)向\(i\)连一条有向边,这样就形成了基环外向树森林。基环外向树森林内每棵基环外向树是相互独立的,需要单独处理。对于每棵基环外向树,任取环上一点\(x\),断开\(x\)到\(fa_{x}\)的有向边,外向树就变成了一棵以\(x\)为根的树。......
  • Enumerating Rational Numbers 题解
    EnumeratingRationalNumbers题解先下结论,这道题是一道欧拉函数板子题观察题面可以发现,生成的分数有如下特性:分数都是最简分数分母与分子互质,且分子$\le$分母当然第一个除外,那个特判即可,不用纳入考虑范围我们知道,对于任意正整数n,欧拉函数,即\(\varphi(n)\)是小......
  • 题解 CF698C【LRU】
    题解CF698C【LRU】题目描述有\(n\)种物品和大小为\(k\)的队列。每次操作,以\(p_i\)的概率选择第\(i\)种物品放入队尾,如果已经有物品\(i\)了就将物品\(i\)拿出来扔到队尾。若队列大小\(\gtk\),弹出队首。求\(10^{100}\)次操作后每种物品在队列里的概率。\(1\leq......
  • upload-labs简单题解
    upload-labs详解1-19关通关全解(最全最详细一看就会)-CSDN博客Upload-labs1-21关靶场通关笔记(含代码审计)_upload-labs21关-CSDN博客搭建upload-labs环境参考文章渗透测试——upload-labs环境部署_upload-loadsphpstudy-CSDN博客文件上传浅谈-CSDN博客 Pass-01考点:J......
  • 题解 ARC175C【Jumping Through Intervals】
    先不考虑构造字典序最小的方案,只考虑求出最小的\(\sum\limits_{i=1}^{N-1}|A_{i+1}-A_i|\)。设定义域为\([L_i,R_i]\)的函数\(F_i(x)\)表示考虑后缀\([i,N]\),令\(A_i=x\)时上式最小的值。初值为\(F_N(x)=0,(x\in[L_N,R_N])\)。显然有转移方程:\[F_i(x)=\min\limits_{y......
  • 题解 CF70E【Information Reform】
    题解CF70E【InformationReform】题目描述\(n\)个点的树,边权为\(1\)。可以花费常数\(k\),在一个点上建基站。每个点\(i\)需要找到离他最近的基站\(a_i\),花费\(d[dis(i,a_i)]\)。一种方案的总花费是建基站的花费加上每个点的花费之和。最小化总花费。输出方案\(a_i\)。......
  • ICPC2023 陕西邀请赛 题解
    G-PermutationQuestion找到一个排列\(p\),使得\(\prod_{i=1}^nlcm(p_i,p_{(imodn)+1})\)最大Solution考虑到\(x\)和\(x-1\)必然是互质的所以顺序排列即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;cin>>n;for(inti......
  • 快递员的烦恼【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-快递员的烦恼快递公司每日早晨,给每位快递员推送需要送到客户手中的快递以及路线信息,快递员自己又查找了一些客户与客户之间的路线距离信息,请你依据这些信息,给快递员设计一条最短路径,告诉他最短路径的距离。注意:不限制快递包裹送到客户手中的顺序,但必须保证都送......