CF Global Round 20:F1. Array Shuffling(最少交换顺序)

博客主要探讨了如何通过最少的交换次数将一个数组b转换成给定的目标数组a。提出了一个结论,即最少操作数等于数组长度减去环的数量,并且环的数量等于出现次数最多的元素的个数。为了最大化操作次数,需要找到最少环的构造方法,通过排序和使用队列记录环的信息。算法实现包括对数组排序、寻找环和记录环的过程。

题目链接:F1. Array Shuffling

题面:

input

2
2
2 1
4

1 2 3 3

output

1 2
3 3 2 1 

题意:给定长度为n的数组a,求一个数组b。可以对b进行交换的操作变成a,记对数组b通过交换变成a的最小操作次数为x。要求构造一个数组b,使得b变为a的最小操作次数最大。

此处有一个结论:排序算法-最少交换次数证明_玉曦的博客-优快云博客_交换次数最少的排序算法

结论就是:如果想要把a[i]->b[j],我们就建立一个条件i->j

最少操作数=n-环的数量

例如:

a: 1 2 3 4 5 6
b: 4 6 1 3 2 5

 

最少操作数为 n-2 。

那么我们希望最少操作数最多,则希望环的数量最少。

如果需要环最少,每个环中无重复元素,则环的个数其实就等于出现次数最多的次数。

 

那么问题来了,如何求最少的环呢?求了后又该如何记录呢?

环的个数:上面描述中可以发现,重复元素最多的次数,就是环的个数。因为每个环中不能出现重复的元素。所以若x为重复的元素,且重复个数为cnt[x],那么就会有cnt[x]个环,每个环中都有一个x。

如何记录:可以对a数组进行排序。排序的方式以重复个数最大为优先,同样的重复个数以数大/小为优先。并存入到一个vector<int> vec中

例如对a:5 6 5 6 1 2 1 1排序的话就变成

1 1 1 5 5 6 6 2或者1 1 1 6 6 5 5 2就行。若以第一个排序方式为例。

形成的环一定是1->5->6->1,1->5->6->1,1->2->1。这样的三个环。

定义二维的队列:unordered_map<int,queue> que;

从前向后遍历,每次把后面vec[i+cnt[vec[i]]]的数的数作为vec[i]的后继,并把这个数标记已经在一个环中了。

若发现vec[i+cnt[vec[i]]]已经被标记过了,那么该数的后继就是最大的重复数。

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+50;
int n;
int a[maxn];
bool st[maxn];
unordered_map<int,int> cnt;
unordered_map<int,queue<int>> que;
int cmp(int a,int b){
    if(cnt[a]!=cnt[b]) return cnt[a]>cnt[b];
    return a>b;
}
void solve(){
    cnt.clear();
    scanf("%d",&n);
    int mx=0;
    for(int i=0;i<n;i++) scanf("%d",&a[i]),cnt[a[i]]++,mx=max(mx,cnt[a[i]]);
    vector<int> vec;
    for(int i=0;i<n;i++) vec.push_back(a[i]);
    sort(vec.begin(),vec.end(),cmp);
    for(int i=0;i<n;i++){
        int t=vec[i];
        if(st[i+cnt[t]]||i+cnt[t]>=n){
            que[t].push(vec[0]);
        }else{
            que[t].push(vec[i+cnt[t]]);
            st[i+cnt[t]]=true;
        }
    }
    for(int i=0;i<n;i++){
        printf("%d ",que[a[i]].front());
        que[a[i]].pop();
    }printf("\n");
    for(int i=1;i<=n;i++)
        while(que[i].size())
            que[i].pop();
    for(int i=1;i<=n;i++) st[i]=false;
}
int main(){
    int t;scanf("%d",&t);
    while(t--) solve();
    return 0;
}

{"t":{"$date":"2025-11-21T10:51:27.629+08:00"},"s":"I", "c":"-", "id":8991200, "ctx":"thread1","msg":"Shuffling initializers","attr":{"seed":539548235}} {"t":{"$date":"2025-11-21T10:51:27.661+08:00"},"s":"I", "c":"CONTROL", "id":97374, "ctx":"thread1","msg":"Automatically disabling TLS 1.0 and TLS 1.1, to force-enable TLS 1.1 specify --sslDisabledProtocols 'TLS1_0'; to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'"} {"t":{"$date":"2025-11-21T10:51:27.916+08:00"},"s":"I", "c":"NETWORK", "id":4915701, "ctx":"thread1","msg":"Initialized wire specification","attr":{"spec":{"incomingExternalClient":{"minWireVersion":0,"maxWireVersion":27},"incomingInternalClient":{"minWireVersion":0,"maxWireVersion":27},"outgoing":{"minWireVersion":6,"maxWireVersion":27},"isInternalClient":true}}} {"t":{"$date":"2025-11-21T10:51:27.918+08:00"},"s":"I", "c":"CONTROL", "id":5945603, "ctx":"thread1","msg":"Multi threading initialized"} {"t":{"$date":"2025-11-21T10:51:27.919+08:00"},"s":"I", "c":"CONTROL", "id":4615611, "ctx":"initandlisten","msg":"MongoDB starting","attr":{"pid":1740,"port":27017,"dbPath":"C:/Program Files/MongoDB/Server/8.2/data/db","architecture":"64-bit","host":"DESKTOP-31EFHO9"}} {"t":{"$date":"2025-11-21T10:51:27.920+08:00"},"s":"I", "c":"CONTROL", "id":23398, "ctx":"initandlisten","msg":"Target operating system minimum version","attr":{"targetMinOS":"Windows 7/Windows Server 2008 R2"}} {"t":{"$date":"2025-11-21T10:51:27.922+08:00"},"s":"I", "c":"CONTROL", "id":23403, "ctx":"initandlisten","msg":"Build Info","attr":{"buildInfo":{"version":"8.2.2","gitVersion":"594f839ceec1f4385be9a690131412d67b249a0a","modules":[],"allocator":"tcmalloc-gperf","environment":{"distmod":"windows"}}}} {"t":{"$date":"2025-11-21T10:51:27.923+08:00"},"s":"I", "c":"CONTROL", "id":51765, "ctx":"initandlisten","msg":"Operating System","attr":{"os":{"name":"Microsoft Windows Workstation (build 17763)","version":"10.0 (build 17763)"}}} {"t":{"$date":"2025-11-21T10:51:27.924+08:00"},"s":"I", "c":"CONTROL", "id":21951, "ctx":"initandlisten","msg":"Options set by command line","attr":{"options":{"storage":{"dbPath":"C:\\Program Files\\MongoDB\\Server\\8.2\\data\\db"}}}} {"t":{"$date":"2025-11-21T10:51:27.926+08:00"},"s":"I", "c":"NETWORK", "id":4648601, "ctx":"initandlisten","msg":"Implicit TCP FastOpen unavailable. If TCP FastOpen is required, set at least one of the related parameters","attr":{"relatedParameters":["tcpFastOpenServer","tcpFastOpenClient","tcpFastOpenQueueSize"]}} {"t":{"$date":"2025-11-21T10:51:27.941+08:00"},"s":"E", "c":"STORAGE", "id":22312, "ctx":"initandlisten","msg":"Error creating journal directory","attr":{"directory":"C:/Program Files/MongoDB/Server/8.2/data/db/journal","error":"boost::filesystem::create_directory: \ufffdܾ\ufffd\ufffd\ufffd\ufffdʡ\ufffd [system:5]: \"C:\\Program Files\\MongoDB\\Server\\8.2\\data\\db\\journal\""}} {"t":{"$date":"2025-11-21T10:51:27.944+08:00"},"s":"E", "c":"CONTROL", "id":20558, "ctx":"initandlisten","msg":"std::exception in initAndListen, terminating","attr":{"error":"boost::filesystem::create_directory: \ufffdܾ\ufffd\ufffd\ufffd\ufffdʡ\ufffd [system:5]: \"C:\\Program Files\\MongoDB\\Server\\8.2\\data\\db\\journal\""}} {"t":{"$date":"2025-11-21T10:51:27.952+08:00"},"s":"I", "c":"REPL", "id":4784900, "ctx":"initandlisten","msg":"Stepping down the ReplicationCoordinator for shutdown","attr":{"waitTimeMillis":15000}} {"t":{"$date":"2025-11-21T10:51:27.959+08:00"},"s":"I", "c":"REPL", "id":4794602, "ctx":"initandlisten","msg":"Attempting to enter quiesce mode"} {"t":{"$date":"2025-11-21T10:51:27.959+08:00"},"s":"I", "c":"-", "id":6371601, "ctx":"initandlisten","msg":"Shutting down the FLE Crud thread pool"} {"t":{"$date":"2025-11-21T10:51:27.963+08:00"},"s":"I", "c":"COMMAND", "id":4784901, "ctx":"initandlisten","msg":"Shutting down the MirrorMaestro"} {"t":{"$date":"2025-11-21T10:51:27.965+08:00"},"s":"I", "c":"SHARDING", "id":4784902, "ctx":"initandlisten","msg":"Shutting down the WaitForMajorityService"} {"t":{"$date":"2025-11-21T10:51:27.966+08:00"},"s":"I", "c":"NETWORK", "id":8314100, "ctx":"initandlisten","msg":"Shutdown: Closing listener sockets"} {"t":{"$date":"2025-11-21T10:51:27.967+08:00"},"s":"I", "c":"NETWORK", "id":4784905, "ctx":"initandlisten","msg":"Shutting down the global connection pool"} {"t":{"$date":"2025-11-21T10:51:27.968+08:00"},"s":"I", "c":"CONTROL", "id":4784906, "ctx":"initandlisten","msg":"Shutting down the FlowControlTicketholder"} {"t":{"$date":"2025-11-21T10:51:27.969+08:00"},"s":"I", "c":"-", "id":20520, "ctx":"initandlisten","msg":"Stopping further Flow Control ticket acquisitions."} {"t":{"$date":"2025-11-21T10:51:27.971+08:00"},"s":"I", "c":"NETWORK", "id":4784918, "ctx":"initandlisten","msg":"Shutting down the ReplicaSetMonitor"} {"t":{"$date":"2025-11-21T10:51:27.973+08:00"},"s":"I", "c":"SHARDING", "id":9439300, "ctx":"initandlisten","msg":"Shutting down the filtering metadata cache"} {"t":{"$date":"2025-11-21T10:51:27.976+08:00"},"s":"I", "c":"NETWORK", "id":20562, "ctx":"initandlisten","msg":"Shutdown: Closing open transport sessions"} {"t":{"$date":"2025-11-21T10:51:27.977+08:00"},"s":"I", "c":"NETWORK", "id":4784923, "ctx":"initandlisten","msg":"Shutting down the ASIO transport SessionManager"} {"t":{"$date":"2025-11-21T10:51:27.979+08:00"},"s":"I", "c":"CONTROL", "id":4784928, "ctx":"initandlisten","msg":"Shutting down the TTL monitor"} {"t":{"$date":"2025-11-21T10:51:27.982+08:00"},"s":"I", "c":"CONTROL", "id":4784929, "ctx":"initandlisten","msg":"Acquiring the global lock for shutdown"} {"t":{"$date":"2025-11-21T10:51:27.985+08:00"},"s":"I", "c":"-", "id":4784931, "ctx":"initandlisten","msg":"Dropping the scope cache for shutdown"} {"t":{"$date":"2025-11-21T10:51:27.987+08:00"},"s":"I", "c":"-", "id":10175800,"ctx":"initandlisten","msg":"Shutting down the standalone executor"} {"t":{"$date":"2025-11-21T10:51:27.988+08:00"},"s":"I", "c":"CONTROL", "id":20565, "ctx":"initandlisten","msg":"Now exiting"} {"t":{"$date":"2025-11-21T10:51:27.989+08:00"},"s":"I", "c":"CONTROL", "id":8423404, "ctx":"initandlisten","msg":"mongod shutdown complete","attr":{"Summary of time elapsed":{"Statistics":{"enterTerminalShutdownMillis":0,"stepDownReplCoordMillis":7,"quiesceModeMillis":0,"stopFLECrudMillis":3,"shutDownMirrorMaestroMillis":1,"shutDownWaitForMajorityServiceMillis":2,"shutDownGlobalConnectionPoolMillis":1,"shutDownSearchTaskExecutorsMillis":0,"shutDownFlowControlTicketHolderMillis":2,"shutDownReplicaSetMonitorMillis":3,"shutDownTransportLayerMillis":4,"shutDownTTLMonitorMillis":2,"shutDownExpiredDocumentRemoverMillis":0,"shutDownOtelMetricsMillis":0,"shutDownFTDCMillis":0,"shutDownReplicaSetNodeExecutorMillis":2,"shutDownOCSPMillis":0,"shutdownTaskTotalMillis":37}}}} {"t":{"$date":"2025-11-21T10:51:27.991+08:00"},"s":"I", "c":"CONTROL", "id":23138, "ctx":"initandlisten","msg":"Shutting down","attr":{"exitCode":100}}
11-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值