本文共 2301 字,大约阅读时间需要 7 分钟。
1、
2、题目大意:
一个序列有n个数字,他们是无序的,现在要将这些数字交换顺序,使得他们是从小到大排列的,输出最少交换几次,3、思路分析
如果数字个数很小的话,实际上是可以用冒泡排序的,冒泡交换的步数实际上就是所求,但是数据很大,所以不能这么做,看网上解题报告用树状数组解决,作为第一个树状数组的题目,真心觉得好难,还得继续看,
还有一个问题就是除了n非常大不能用冒泡做,还有就是这n个数字也是非常大的,所以要用到离散化
4、题目
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 37365 | Accepted: 13438 |
Description
Input
Output
Sample Input
59105431230
Sample Output
60
Source
5、AC代码:
#include#include #include using namespace std;#define N 500005int b[N],n,c[N];struct node{ int id; int x;} a[N];int cmp(node a,node b){ return a.x 0) { tmp+=c[i]; i-=i&(-i); } return tmp;}int main(){ while(scanf("%d",&n)!=EOF) { if(n==0) break; memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); for(int i=1; i<=n; i++) { scanf("%d",&a[i].x); a[i].id=i; } sort(a+1,a+n+1,cmp); //离散化 a[0].x=-1; for(int i=1; i<=n; i++) { if(a[i].x!=a[i-1].x) b[a[i].id]=i; else b[a[i].id]=b[a[i-1].id]; } long long ans=0; for(int i=1; i<=n; i++) { //每次更新后判断左边比当前数大的数的个数 update(b[i],1); ans+=sum(n)-sum(b[i]); } printf("%lld\n",ans); } return 0;}
转载地址:http://owcdi.baihongyu.com/