首页 > 其他分享 >cf-置换环问题

cf-置换环问题

时间:2023-01-11 12:44:20浏览次数:48  
标签:pp int res 置换 交换 cf long 问题 逆序

 

 

Problem - D - Codeforces

题意:

  给你一个排列组合a数组,你每次操作可以交换某a数组中的某两个元素,求最小交换次数,使得得到的a数组中只含有一个逆序对

解题思路:

  拓展结论:冒泡排序所需要的最少交换次数就是该数组逆序对的总个数(这题用不到)

  首先题目要求我们只有一个逆序对,言下之意除了a【i】和a【i+1】这两个元素外其他元素均为有序,因此我们可以先把整个数组排成有序的,然后再用一次交换得出一个逆序对。

  而如果我们对于每个i建立i和a[i]之间的边,就会得到很多的环,意思是a[i]到他该去的位置,形成一个内部的闭环,而要想使得数组有序,且交换次数最少,交换只会在环内发生,不存在环间的交换

  例如以下排列

 

 

我们看看那个4个点的环

 

 

 

在排列上,进行交换

 

进行了三次交换,就使得环内有序

 

 言下之意,在一个元素个数为n的环中,需要进行n-1次交换才能使得环内有序

因此我们统计出总环数为res

用此让整个数组有序的最小操作次数为n-res

答案为n-res+1

但是,还有一种情况。

对于上面的4个点的环,我们这样交换

 

此时a【2】和a【3】组成了一个逆序对,少了一步操作且也创造出了一个逆序对,于是总操作次数为n-res-1

 

 也就是,如果环中,有相邻的两个点,那么可以通过减少一次交换,使得其贡献出一个逆序对。

 

代码实现

 

 

#include <bits/stdc++.h>
using namespace std;
const long long maxx = 0x3f3f3f3f3f3f3f3f;
const long long minn = 0xc0c0c0c0c0c0c0c0;
const double pi = 4.0 * atan(1.0);
#define int long long
#define f(i, n, m) for (long long i = n; i <= m; ++i)
#define unf(i, n, m) for (long long i = n; i >= m; --i)
#define kong NULL
#define debug cout << "sss" << endl;

map<int, int> mp;
map<int, int> check;
void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 10, 0);
    check.clear();
    mp.clear();
    f(i, 1, n)
    {
        cin >> a[i];
        mp[a[i]] = i;
    }
    int ff = 1;
    int res = 0;
    f(i, 1, n)
    {
        if (check[i])
            continue;
        map<int, int> o;
        int pp = i;
        check[pp] = 1;
        while (!o[pp])
        {
            if (o[pp - 1] || o[pp + 1])
                ff = -1;
            o[pp] = 1;
            pp = mp[pp];
            check[pp] = 1;
        }
        res++;
    }
    cout << n - res + ff << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    int _;
    cin >> _;
    while (_--)
    {
        solve();
    }
    // solve();
    return 0;
}

 

标签:pp,int,res,置换,交换,cf,long,问题,逆序
From: https://www.cnblogs.com/shifangchen/p/17043387.html

相关文章

  • LeetCode刷题:AddressSanitizer: heap-buffer-overflow问题请教||全局变量和引用传递的
    在刷https://leetcode.cn/problems/sudoku-solver/description/遇到AddressSanitizer:heap-buffer-overflow的报错。代码为://本题思路就是简单的回溯//注意限制:只......
  • 一个CF1775C(Codeforces Round #843 (Div. 2))的小技巧
    若\(n\)的第\(i\)位为\(1\),而我们需要不断令\(n+1\)找到下一个最小的\(k\),使得\(k\)的第\(i\)位为\(0\)。技巧:假设\(n\)为10101[1]1001,括号内是要求的第\(i\)位那么先......
  • ESP-IDF4.4 VScode安装问题
    一般安装ESP-IDF的环境是不会出错的,一路点击下去即可【ESP-IDFv4.4.3-OfflineInstaller下载地址】。主要是VScode安装ESP-IDF插件的时候会有以下两个问题WARNING:Y......
  • el-table更新数据页面闪烁问题
    情况是这样,渲染了一个table,高度是固定的。所以会有滚动。其中的某一列的数据只显示了部分内容,鼠标浮上加载全部,用el-popover浮框显示。  但每次改变tableKey会触发整......
  • 解决mui picker选择器在 ios16.2系统上,选择器滚动错误错乱,无法正常选择的问题
    操作步骤:16.2版本的ios手机,使用mui.picker控件,就会出现此问题,百分百复现。预期结果:mui.picker控件在ios16.2系统正常使用实际结果:无法正常使用bug描述:muipick......
  • CF Codeforces Round #843 (Div. 2)
    CodeforcesRound#843(Div.2)本次脑袋不大灵光,一方面可能是怕掉分。另一方面就是交的人实在是太少了,导致我一直不敢交,其实这场cf没有我想象中那么难,甚至来说我一直是......
  • CF1624 DEG
    D题面大意$n$个字母的字符串,选出$m$个子串(不一定连续,但每个字符串长度至少$1$);子串字母可随意交换;让所有子串都是回文串,而且最短的那个尽可能长。求出最短那......
  • 如何解决海外服务器IP被封的问题?
    我们在使用服务器​​​​的时候,为了符合各机房或服务商的使用规定,同时也要承担一定的风险,比如内容违规以及常见的封禁服务器IP的处罚,为了避免不必要的损失,一定要了解各地区......
  • CF843记录
    正序开题A直接做完整版,一开始读错题了以为是任意字符串,想出来之后回去看题,发现只有ab,写了140+行的分讨,20:00才过。B又读错题以为是异或,想了一会儿发现读错题了,水题......
  • 【FAQ】推送服务常见问题及解决方案
    一、推送成功收不到消息,推送返回:{"message":"success","requestID":"1523868*****2842718","resultcode":0}排查步骤:1、网络不稳定,切换稳定网络进行测试;2、检查手机是否......