首页 > 其他分享 >2024牛客暑期多校训练营7 C Array Sorting 题解

2024牛客暑期多校训练营7 C Array Sorting 题解

时间:2024-08-06 23:39:17浏览次数:11  
标签:Sorting int 题解 ++ 多校 len back vis ans

乱搞

非正解写法。分类讨论各种情况。

  • 降序排序

对应交换即可

  • 数组个数小

直接考虑相邻的交换

  • 其他都看做随机数据

考虑结合前面情况,很容易想到,先把数组变成一个尽量有序的数组(每个元素和自己正确的位置相差不大)。最后再多次相邻交换,使得每个元素都在正确位置。

把数组变成一个尽量有序的过程,很容易想到希尔排序。我们做一个类似希尔排序的操作,每次设定\(d\),使\(i\)和\(i+d\)交换,然后\(d/=2\)。多次进行这样的操作,但是发现每次都有些位置\(j\)一直是和\(j-d\)交换的,在这些位置不少于某个值的时候,我们考虑让\(j\)和\(j+d\)交换,这样我们就得到了个尽量有序的数组。

很好的过样例,submit WA。剩下的就是调参的内容了。写一份check代码。打印每次选择的有序对时,成功交换的比例,调参使得前几次交换比例高,后面交互比例为0。你问我正确性?我也不知道,我只能说本地随机一百组数据都是可以通过的。

细节:
  • 特判\(n=0,1\)
  • 注意每个有序对\((x,y)\),\(x\)都小于\(y\)
  • 一个位置一次交换只能出现一次
  • \(d\)的选择不能每次都是\(n\)的因数,不然有些值一直在某些固定位置选择,并且不动。
vector<pii>ans[205];
bool vis[MAXN];
void solve() {
    n = read();
    if (n == 1) return printf("0\n"), void();
    if (n == 2) return printf("1\n1 0 1\n"), void();
    for (int i = 0, j = n - 1; i < j; ++i, --j)
        ans[1].push_back({i, j});
    m = 2;
    if (n <= 10) {
        for (; m <= 200; ++m) {
            for (int i = 1 - (m & 1); i + 1 < n; i += 2) {
                int x = i, y = i + 1;
                if (x > y)swap(x, y);
                ans[m].push_back({x, y});
            }
        }
    } else {
        for (int k = 0; k < 24; ++k) {
            for (int len = 10000 >> (k + 1); len >= 5; len >>= 1) {
                if (len > n / 2)continue;
                memset(vis, 0, sizeof(vis));
                for (int i = 0; i + len < n; ++i) {
                    int x = i, y = i + len;
                    if (x > y)swap(x, y);
                    if (!vis[x] && !vis[y]) {
                        vis[x] = vis[y] = 1;
                        ans[m].push_back({x, y});
                    }
                }
                ++m;
                if (len >= n / 10)continue;
                memset(vis, 0, sizeof(vis));
                for (int i = len; i + len < n; ++i) {
                    int x = i, y = i + len;
                    if (x > y)swap(x, y);
                    if (!vis[x] && !vis[y]) {
                        vis[x] = vis[y] = 1;
                        ans[m].push_back({x, y});
                    }
                }
                ++m;
            }
        }
        for (; m <= 200; ++m) {
            for (int i = 1 - (m & 1); i + 1 < n; i += 2) {
                int x = i, y = i + 1;
                if (x > y)swap(x, y);
                ans[m].push_back({x, y});
            }
        }
    }
    printf("%d\n", m - 1);
    for (int i = 1; i < m; ++i, enl) {
        printf("%d ", ans[i].size());
        for (auto& [x, y] : ans[i])printf("%d %d ", x, y);
    }
}

标签:Sorting,int,题解,++,多校,len,back,vis,ans
From: https://www.cnblogs.com/Qing17/p/18346192

相关文章

  • 洛谷 P4910题解
    题目大意现在穿T次手串,每根手串的长度分别为不同的n,有木和金两种珠子,相邻两颗珠子必须有一个是金。题目思路分析我们现在设穿到第n个珠子时用金的方案数为f[1][n],用木的方案数为f[0][n]如果第n个珠子为金,那么前一颗珠子是什么都可以,因此f[1][n]=f[1][n-1]+f[0][n-1]而如果......
  • CF573E Bear and Bowling 题解
    Description给定一个长度为\(n\)的序列\(a_{1\dotsn}\)。你要求一个\(a\)的子序列\(b_{1\dotsm}\)(可以为空),使得\(\sum_{i=1}^mib_i\)的值最大。\(n\le10^5\),\(|a_i|\le10^7\)。Solution有一个显然的dp是设\(f_{i,j}\)表示前\(i\)个数,选\(j\)个数的......
  • CF1920D题解
    题面这里不再赘述了,直接搬个链接。InLuoguInCodeforces思路存储一共两种操作:要么在末尾加一个数xxx,要么把整一段复制......
  • NSSCTF靶场题解(6)
    站在小白的视角上,写了在写题目的wp方面更多是想体现题目思考的逻辑和细节,更多是写给同样新手小白的内容,解题方面为什么从这一步到下一步的,很助于培养思考题目的逻辑思维,尽我所能把细节阐释到位,有些地方可能理解说辞不是特别到位,如果有问题就麻烦各位大佬师傅指点~这次题解库收......
  • 题解:CF257C View Angle
    题目传送门题意平面上有\(n\)个点。从原点引出两条射线,将平面分成两个部分,使其中一个部分覆盖所有的点。求这个部分与原点所夹的角的最小度数。思路既然一个部分覆盖了所有的点,那么另一个部分就一个点都没覆盖,那么要让这个部分最优,这两条射线一定经过两个中间没有任何点的点......
  • 2024牛客暑期多校训练营7
    Preface久违地打的像人的一场,在开局即红温的条件下后面还能放好心态打还是很不容易的前期我被I单防红温了,还好有祁神救场上去帮我过了这个题,然后徐神秒出D的做法扔给我我爬上去实现了下很快过了由于想不出C这个神秘构造的做法,只能经典地让我中期占机子写大模拟H,想我这种......
  • 【题解】暑假集训CSP提高模拟14
    目录Rank&挂分A.BA题目内容部分分10pts10+20pts正解思路代码B.BB题目内容部分分5pts正解思路代码C.BCD.BDRank&挂分T4暴搜后来改了记搜,不知道哪里锅了,挂5pts。A.BA题目内容现在有\(m\)块烙板,\(n\)张饼,第\(i\)张饼需要烙\(a_i\)个单位时间,一张饼一个单位时刻只能......
  • 2024MX-MF-DAY1-text题解
    T1【题目描述】有\(n\)个人按编号从\(1\)到\(n\)坐成一圈,即第\(i\in[1,n]\)个人右边是\(i+1\),第\(n\)个人右边的人是\(1\)。初始,每个人手上有\(m\)个球。随后,\(n\)个人按编号从小到大的顺序依次执行如下操作:把自己手中的球分成数量相同且尽可能多的三份,......
  • AkSoundSeedAir.dll修复指南:游戏音频问题解决与预防技巧
    AkSoundSeedAir.dll是一个与声音引擎相关的动态链接库(DynamicLinkLibrary,简称DLL)文件,尤其与Wwise(AudiokineticWwise)声音设计和游戏音效中间件有关。Wwise是一个广泛应用于游戏开发的声音引擎,用于处理游戏中的音频和音效,AkSoundSeedAir.dll就是Wwise的一部分,用于实现声音处理......
  • 花园改造 题解
    题目id:9989题目描述小\(X\)开始改造她的环形的花园了,具体来说她要在花园的环上种满\(n\)棵树。她现在有\(3\)种树:种子、小树苗和大树。每个位置上种不同的树会产生不同的满意度,具体来说在第\(i\)个位置,种种子会产生\(a_i\)的满意度,种小树苗会产生\(b_i\)的满意度,种大树会产生\(c......