问题 A: 最少的交换

题目链接问题 A: 最少的交换
题解:由于是相邻的交换得到最少次数,即求逆序对的个数。
即求数组每个位置上左边大于该位置的值的个数,于是可以用数组数组求解。
因为题目数据范围为0-999999999,无法开数组,可以使用结构体存储值和位置,对值进行排序,因为只需要比较大小不在意具体的值多少,这样就可以将原来的数组的值按照排名从1-n重新定义,存储到另一数组中。
例如 9 1 0 5 4
坐标 1 2 3 4 5
排序后 0 1 4 5 9
原坐标 3 2 5 4 1
重新定义值为 1 2 3 4 5 按照原来数组的下标存储到另外一个数组中:
5 2 1 4 3
在使用树状数组求解

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
typedef struct Node{
	int val;
	int pos;
}Node;
bool cmp(Node n1, Node n2) {
	return n1.val < n2.val;
}
#define lowbit(x) ((x) & (-x))
int getSum(int x);
void updata(int x, int v);
const int maxn = 500100;
Node arr[maxn];
int c[maxn], a[maxn];
int n;
int main(int argc, char** argv) {

	while (scanf("%d", &n) && n != 0) {
		memset(c, 0, sizeof(c));
		for (int i = 1; i <= n; i++) {
			scanf("%d", &arr[i].val);
			arr[i].pos = i;
		}
		// 离散化 
		sort(arr + 1, arr + n + 1, cmp);

		a[arr[1].pos] = 1;
		for	(int i = 2; i <= n; i++) {
			if (arr[i].val == arr[i - 1].val) {
				a[arr[i].pos] = a[arr[i - 1].pos];
			} else {
				a[arr[i].pos] = i;
			}
		}
		long long sum = 0;
		for (int i = 1; i <= n; i++) {
			updata(a[i], 1);
			sum += getSum(n) - getSum(a[i]);
		}
		printf("%lld\n", sum); // 忘了lld 
	}
	return 0;
}
/**
5
9 1 0 5 4
3
1 2 3 0
*/
int getSum(int x) {
	int sum = 0;
	for (int i = x; i > 0; i -= lowbit(i))
		sum += c[i];
	return sum;
} 
void updata(int x, int v) {
	for (int i = x; i <= n; i += lowbit(i))
		c[i] += v;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值