【题解】AT_abc276_c 题解

AT_abc276_c 题解

思路分析

这道题可以用 STL,有大佬已经讲过了,我就来讲一个不用 STL 的做法。这个做法其实也是 STL 内部的实际做法。

这个做法分三步:

  1. 从右往左找到第一个不满足递减的数(即比它后面的数大)。因为如果是字典序最小的排列,从左往右一定递减。而题目保证不会输入字典序最小的排列,所以一定会有这个数。我们令这个数为 qq

  2. 从右往左找到第一个在 qq 后面且小于 qq 的数 pp,并将 ppqq 交换。由于这个数是第一个,所以可以保证所有在 qq 后面的数从小到大排列。

  3. 将所有在 qq 原来位置(即现在的 pp 所在的位置)的后面的数反转,这样可以保证所有在 qq 后面的数从大到小排列。这样就可以保证这就是按照字典序的上一个排列。

关键代码

void change()
{
	int cur = n;
	int pre = n - 1;//初始化下标
	while(cur > 1 && a[pre] <= a[cur]) //从右往左找到第一个不满足递减的数 q(即比它后面的数大)
	{
		cur--;
		pre--;//往前找
	}
	cur = n;//重置下标
	while(a[cur] >= a[pre])//从右往左找到第一个在 q 后面且小于 q 的数
	{
		cur--;
	}
	swap(a[pre], a[cur]);//交换 p 和 q
	reverse(a + pre + 1, a + n + 1);//反转 p 后面的数
}
posted @ 2022-11-13 11:59  邻补角-SSA  阅读(20)  评论(0)    收藏  举报  来源