Inversion

题目链接:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=52584

题意:

       先输入两个数n,k,n表示这组数的个数,k表示最多可以交换的次数,再输入一组数,交换相邻的数使它是从小到大排序,交换次数不能大于k,问,你交换到最后,还会有多少个倒置数。

      案例:

      input

      3 1

      2 2 1

      3 0

      2 2 1

      output

      1

      2

思路分析:

         在第一个案例中,最多交换一次,我要尽可能的使它从小到大排序,那么只能交换相邻的1,2,这样得到的是1,简单来说,就是在这些数中,在它前面却比它大的数的总和减去可以交换的数k就是所得答案,这让我想到归并排序,归并排序可以求出在它前面却比它大的数的总和。这样就可以得出答案。

         但是要注意一种情况,当需要交换的次数小于k呢?在这种情况输出0就行。

         注意:数的范围过大,要用long long型。

源代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #define MAX 100005
 4 using namespace std;
 5 int n;
 6 long long a[MAX],t[MAX],s,k;
 7 void merge_sort(long long *A,long long x,long long y,long long *T)
 8 {
 9     if(y-x>1)
10     {
11         long long m=x+(y-x)/2;
12         long long p=x,q=m,i=x;
13         merge_sort(A,x,m,T);
14         merge_sort(A,m,y,T);
15         while(p<m||q<y)
16         {
17             if(q>=y||(p<m&&A[p]<=A[q])) T[i++]=A[p++];
18             else {T[i++]=A[q++];s+=m-p;}     //需要交换次数
19         }
20         for(i=x;i<y;i++)A[i]=T[i];
21     }
22 }
23 int main()
24 {
25     while(scanf("%d%d",&n,&k)!=EOF)
26     {
27         s=0;
28         for(int i=0;i<n;i++)
29             scanf("%d",&a[i]);
30         merge_sort(a,0,n,t);
31         if(s>=k)
32             cout<<s-k<<endl;
33         else
34             cout<<"0"<<endl;
35     }
36     return 0;
37 }

 

转载于:https://www.cnblogs.com/q-c-y/p/4713457.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值