码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-02-06 21:09:24      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:固定   memset   alien   color   ++   循环   最小   ems   def   

给出一个长度不超过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\n",ans);
35     }
36     return 0;
37 }

 

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

标签:固定   memset   alien   color   ++   循环   最小   ems   def   

原文地址:https://www.cnblogs.com/asdfsag/p/10354061.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!