UVA - 10570 Meeting with Aliens (置换的循环节)

Posted asdfsag

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA - 10570 Meeting with Aliens (置换的循环节)相关的知识,希望对你有一定的参考价值。

给出一个长度不超过500的环状排列,每次操作可以交换任意两个数,求把这个排列变成有序的环状排列所需的最小操作次数。

首先把环状排列的起点固定使其成为链状排列a,枚举排好序时的状态b(一种有2n种可能),则b可以看成是原状态a的一个置换,把a变为b所需的最小交换次数即为a的长度n减去置换循环节的数量。

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 const int N=500+10;
 6 const int inf=0x3f3f3f3f;
 7 int n,a[N],b[N],c[N],vis[N],ans;
 8 
 9 int cir(int* a,int* b,int n) {
10     int ret=0;
11     memset(vis,0,sizeof vis);
12     for(int i=1; i<=n; ++i)c[a[i]]=b[i];
13     for(int i=1; i<=n; ++i)if(!vis[i]) {
14             ++ret;
15             for(int j=i; !vis[j]; j=c[j])vis[j]=1;
16         }
17     return ret;
18 }
19 
20 int main() {
21     while(scanf("%d",&n)&&n) {
22         ans=inf;
23         for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
24         for(int i=1; i<=n; ++i)b[i]=i;
25         do {
26             ans=min(ans,n-cir(a,b,n));
27             for(int i=1; i<n; ++i)swap(b[i],b[i+1]);
28         } while(b[1]!=1);
29         for(int i=1; i<=n; ++i)b[i]=n-i+1;
30         do {
31             ans=min(ans,n-cir(a,b,n));
32             for(int i=1; i<n; ++i)swap(b[i],b[i+1]);
33         } while(b[1]!=n);
34         printf("%d
",ans);
35     }
36     return 0;
37 }

 

以上是关于UVA - 10570 Meeting with Aliens (置换的循环节)的主要内容,如果未能解决你的问题,请参考以下文章

UVa10570 Meeting with Aliens (枚举)

UVa 10570 - Meeting with Aliens

UVa - 10570 - Meeting with Aliens

uva10570 Meeting with Aliens

UVa 10570 Meeting with Aliens (暴力)

UVA - 10570 Meeting with Aliens (置换的循环节)