ACdream 1038 (想法+排序)

题目:ACdream 1038 (想法+排序)

思路:
1. 这一题的题意是将打乱了的数字归于原位,每一次交换2个数字的位置,如果有k个交换机会,最多有几个数字归于原位。
2. 这一题你会发现无论数字怎样打乱都会形成一个一个的环,假设由n个数字组成一个环,那么只需要交换n-1次即可将所有的位置还原,如果不足n-1次的交换机会,那么你至少可是使k个数字还原。
3. 由于题目是k次使最多的数字归位,那么在事先统计出了各个环的数量后,就排序,先解决小环,再解决大环,就这样。
4. 那么这一题的流程就分为:输入->统计环数->将环数排序->从小到大解决->输出

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Max 100001
 
int flag[Max], huan[Max], number[Max];
 
int cmp( const void *a, const void *b)
{
    return *(int*)a - *(int*)b;
}
 
int main()
{
    int n,k;
    int result,temp;
    int i, nu,cicle;                /*控制数组*/
    while (scanf("%d%d",&n,&k)!=EOF)
    {
        result=0;
        memset(flag, 0, sizeof(flag));
        memset(huan, 0, sizeof(huan));
        memset(number, 0, sizeof(number));
     
        for (i=0; i<n; i++)
        {
            scanf ("%d",&number[i]);
            if(i==number[i])            /*将已经归位原位的数字统计*/
            {
                flag[i]=1;
                result++;
            }
        }
 
        nu=0;
        for( i=0; i<n ;i++)
        {
            cicle=0;                    /*统计环的大小,环的个数*/
            temp=i;
             
            while (flag[temp]==0)
            {
                cicle++;
                flag[temp]=1;
                temp=number[temp];
            }
 
            if(cicle>1)
                huan[nu++]=cicle;
        }
         
        qsort( huan, nu, sizeof (huan[0]), cmp);     /*按照换的大小排序*/
        for( i=0; i<nu ; i++)               /*统计归位的数字*/
        {
            if ( k<(huan[i]-1))
            {
                result=result+k;
                break;
            }
            else
            {
                result+=huan[i];
                k=k-(huan[i]-1);
            }
        }
         
        printf("%d\n",result);
    }
 
    return 0;
}
/**************************************************************
    Problem: 1038
    Language: C
    Result: Accepted
    Time:100 ms
    Memory:2080 kb
****************************************************************/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值