8.17腾讯笔试开发岗第二题

逆序对问题
简介:先对字符串做一个部分翻转,求得翻转结果里逆序串的个数(两个数字之前前面数字比后边大,组成一个逆序串,如3,2,1中,3,1;2,1,分别是两个逆序串)。

用例:
第一行n:2 //表示目标数据个数为2^n个
第二行:2 1 4 3//表示这个长度为4的数据串的各个值
第三行:4 //做4次变换
第四行:1 2 0 2 //每次的变换空间大小

输出:
0 //输入2,1,4,3,以2^1为步长,变换为1,2,3,4,完全顺序排列逆序对个数为0
6//输入1,2,3,4 以2^2为步长,变换为4,3,2,1,完全顺序排列逆序对个数为6
6//输入4,3,2,1 以2^0为步长,变换为4,3,2,1,完全顺序排列逆序对个数为6
0//输入4,3,2,1 以2^2为步长,变换为1,2,3,4,完全顺序排列逆序对个数为6
输入:
2
2 1 4 3
4
1 2 0 2

输出:
0
6
6
0

思路也比较简洁,毕竟笔试没太多时间想精巧方法。
第一步先翻转,用到了一个抑或交换两数的技巧
第二步计数逆序对,我感觉这块自己做的不太好,也因为这里超时了,只过了50%用例。有兴趣的朋友可以给提点改进意见,但是整理来说比较容易看懂。

#include<iostream>
using namespace std;
void reverse(int targetSize, int * target, int step) {
	if (step == 1)
		return;
	for (int i = 0; i < targetSize; i+= step)
	{
		for (int j = 0; j < step; j += 2)
		{
			//target[i+j]与target[i+step-1-j]交换
			target[i + j] = target[i+j]^target[i+step-1-j];
			target[i+step-1-j] =target[i+j]^target[i+step-1-j];
			target[i + j] = target[i + j]^target[i+step-1-j];
		}
}
int countNXD(int dataSize,int *data) {
	int ret=0;
	for (int i = 0; i < dataSize-1; i++)
	{
		for (int j = i+1; j < dataSize; j++) {
			if (data[i] > data[j])
				ret++;
		}
	}
	return ret;
}
int main() {
	int n;
	cin >> n;
	if (n == 0)
	{
		cout << 0;
		return 0;
	}
	int dataSize = pow(2,n);
	int * data= new int [dataSize];
	for (int i = 0; i < dataSize; i++) {
		cin >> data[i];
	}
	int m;
	cin >> m;
	int *test = new int[m];
	for (int i = 0; i < m; i++)
	{
		cin >> test[i];
	}
	for (int i = 0; i < m; i++)
	{
		int ret;
		reverse(dataSize,data, pow(2,test[i]));
		ret=countNXD(dataSize,data);
		cout << ret<<endl;
	}
	delete[]data;
	delete[]test;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值