pat1067

来源:互联网 发布:淘宝助理 菜鸟打印 编辑:程序博客网 时间:2024/06/05 11:18

这题我用了差不多是离散数学里的置换群(其实我也不记得是不是叫置换群,反正这个群里的一些数位置错了,可以通过某个数发起,把这些数换到自己对应的位置)的思想,假如我们找到一个置换群,这个置换群包括0,那么置换群里有多少个数(包括0)我们就换多少次就好了,假如没有0,那么我们先要把0加入到这个置换群(就是置换群中的某个数和0换一个位置)继续刚才的做法。至于做法总数的话,我现在假设0就在0这个位置,那么每次换,我都得把0加入一个置换群,次数就是需要换的数加上置换群的个数,但是0要是不在0这个位置呢?那么我们可以减少2步,第一我们不需要把0加入一个置换群中,因为0已经属于一个置换群了。第二加入后置换群中的数的个数多了1,步数也多算了一次,所以把这2步减掉就好了。代码如下:

#include<stdio.h>int a[100001];int mark[100001];int main(){int n,i;while(scanf("%d",&n)!=EOF){int cnt=0;int flag=0;int ans=0;for(i=0;i<n;i++){scanf("%d",a+i);mark[i]=0;if(a[i]!=i)cnt++;else {mark[i]=1;if(i==0)flag=1;}}for(i=0;i<n;i++){if(mark[i]==0){int tmp=i;mark[i]=0;while(a[tmp]!=i){mark[a[tmp]]=1;tmp=a[tmp];}ans++;}}ans=ans+cnt;if(flag==0)ans-=2;printf("%d\n",ans);}return 0;}


原创粉丝点击