codeforces刷题(1100):1863B_div1+div2

发布时间 2023-12-30 19:20:03作者: Tom-catlll

B、Split Sort

跳转原题点击此:该题地址

1、题目大意

  给定一个长度为n的排列(该排列的数字是包含\(1\sim n\),每个数必须出现一次)。你可以执行以下操作:
  选中一个数x,比x的数按照原来的顺序放在x的左边,大于等于x的数按照原来的顺序放在x的右边。问你 将 原始排列组成\(a_i == i,i\subseteq (1\sim n)\)的递增排列,最少需要操作几次。

2、题目解析

  我们发现当\(x-1\)\(x\)的右边时,则需要操作一次将\(x-1\)移动到\(x\)的左边,所以只需要找到该数列中有几个这样的数对,那就是至少需要的操作数。

3、具体代码

#include<bits/stdc++.h>

using namespace std;

const int N = 2e5+10;

int T;
int n;
int f[N];

// 原理:如果 x-1 在 x的右边,那么就需要选中x来将x和x-1调换位置
// 所以找到几个这样的数即可
void solve()
{
	cin >> n;
	vector<int> f(n + 1);
	set<int> se;
	int ans = 0;
	for(int i = 1; i <= n; i++)
	{
		cin >> f[i];
		if(f[i] != 1 && !se.count(f[i] - 1))
			ans++;
		se.insert(f[i]);	// 注意,每次都要插入排列
	}
	cout << ans << endl;
}

int main()
{
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}