【思维题】CodeForce 1007A Reorder the Array

版权声明:Johnson https://blog.csdn.net/m0_38055352/article/details/91356718

这段时间要沉迷刷题一段时间了,就让CSDN陪我一起吧!

一、题目大意

题目的意思是说给你一个长度为n的整数序列,要求你进行重排,重排的要求是尽可能的使每个位置上的数变大,比如原来下标1位置是1,重排后下标1位置是3,那么这就是变大了,最后要求重排后变大的下标数的最大值。

二、题目思路以及AC代码

对于这道题,还是可以很容易想到暴力的解法,那就是直接遍历所有的排列情况,然后求取每种排列情况变大的下标值,然后求取最大值,当然这显然是不可取的,复杂度太高了。

那么我们就要考虑如何给定他一个策略,按照这个策略就可以找到变大的下标数的最大值。我们可以这样,把数组中最大的数放到第二大的位置上,然后把第二大的数放到第三大的位置上,这样可以保证损失最小,也就可以保证下标变大的数尽可能的多,但需要注意的是最大的数可能有多个,第二大的数也可能有多个,需要仔细处理一下。

下面给出AC代码:

#include <iostream>
#include <algorithm>
#define MAXN 100010
using namespace std;

typedef pair<int, int> pp;

int n;
pp a[MAXN];

bool cmp(pp a, pp b) {
	return a.first > b.first;
}

int main()
{
	cin >> n;

	for (int i = 0; i < n; i++) {
		a[i].second = i;
		cin >> a[i].first;
	}

	sort(a, a + n, cmp);
	bool* b = new bool[n];
	for (int i = 0; i < n; i++) {
		b[i] = false;
	}

	int cnt = 0;
	for (int i = 0; i < n; i++) {
		int j = i + 1;
		while (b[j] || (j < n && a[j].first == a[i].first)) {
			j++;
		}
		if (j >= n) break;
		b[j] = true;
		cnt++;
	}

	cout << cnt << endl;

    return 0;
}

如果有问题,欢迎大家指正!!!

猜你喜欢

转载自blog.csdn.net/m0_38055352/article/details/91356718