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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章