【题解】AT_abc276_c 题解
AT_abc276_c 题解
思路分析
这道题可以用 STL,有大佬已经讲过了,我就来讲一个不用 STL 的做法。这个做法其实也是 STL 内部的实际做法。
这个做法分三步:
-
从右往左找到第一个不满足递减的数(即比它后面的数大)。因为如果是字典序最小的排列,从左往右一定递减。而题目保证不会输入字典序最小的排列,所以一定会有这个数。我们令这个数为 。
-
从右往左找到第一个在 后面且小于 的数 ,并将 和 交换。由于这个数是第一个,所以可以保证所有在 后面的数从小到大排列。
-
将所有在 原来位置(即现在的 所在的位置)的后面的数反转,这样可以保证所有在 后面的数从大到小排列。这样就可以保证这就是按照字典序的上一个排列。
关键代码
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 后面的数
}

浙公网安备 33010602011771号