题目
给定长度为n(n<=9)的全排列,
输出比该全排列上一个字典序的全排列,
不存在输出ERROR
思路来源
https://www.luogu.com.cn/problemnew/solution/P2525
题解
组合数学恶补第二弹,orz这个可是洛谷入门题
考虑上一个字典序,一定出现在某一位比当前全排列小了,且是最靠后的一位
对于相邻的正序对,无法交换其顺序,所以一定是从后往前的第一个逆序对
若a[i-1]>a[i],则可以把a[i-1]调小,变成字典序更小的全排列,
所以找到范围内满足a[x]<a[i-1]且值最大的那个位置x,将其与a[i-1]交换,
交换之后,起到了降字典序的目的,后面的数应降序排列,使当前的字典序最大
代码1
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=10;
int n,a[N],b[N],cnt;
bool ok;
void solve(int x){//[x,n)
int mx=-1,pos=-1;
for(int i=x+1;i<n;++i){//<a[x]的最大的 从最小的逆序一位开始调小
if(a[i]<a[x]){
if(a[i]>mx){
mx=a[i];
pos=i;
}
}
}
swap(a[pos],a[x]);
sort(a+x+1,a+n,greater<int>());//后面的降序即可 表示此时的最大
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
}
for(int i=n-1;i;--i){
if(a[i-1]>a[i]){
solve(i-1);
for(int j=0;j<n;++j){
printf("%d%c",a[j]," \n"[j==n-1]);
}
ok=1;
break;
}
}
if(!ok)puts("ERROR");
return 0;
}
代码2(prev_permutation)
用STL水,调用该函数,若上一个全排列存在,则会使ai变成上一个全排列,否则返回假
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=10;
int n,a[N],b[N],cnt;
int main(){
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&a[i]);
}
if(!prev_permutation(a,a+n))puts("ERROR");
else{
for(int i=0;i<n;++i){
printf("%d%c",a[i]," \n"[i==n-1]);
}
}
return 0;
}
后续(2021.5.7)
下一个全排列类似,可以参考1850. 邻位交换的最小次数
class Solution:
def getMinSwaps(self, num: str, k: int) -> int:
def getnext(nums):
n = len(nums)
for i in range(n-2,-1,-1):
if nums[i]<nums[i+1]:
mn, pos = '9', -1
for j in range(i+1,n):
if num[j]>nums[i]:
if mn > nums[i]:
mn, pos = nums[j], j
nums[i],nums[pos] = nums[pos],nums[i]
nums[i+1:n] = sorted(nums[i+1:n])
return nums
tmp = list(num)
num = list(num)
n = len(num)
ans = 0
for i in range(k):
num = getnext(num)
# print(num)
for i in range(n):
if tmp[i] == num[i]:
continue
pos = -1
for j in range(i+1,n):
if num[j] == tmp[i]:
pos = j
break
for j in range(pos,i,-1):
num[j],num[j-1] = num[j-1],num[j]
ans += 1
return ans
['9', '4', '8', '6', '5', '3']
['9', '5', '3', '4', '6', '8']
['9', '5', '3', '4', '8', '6']
['9', '5', '3', '6', '4', '8']
['9', '5', '3', '6', '8', '4']
['9', '5', '3', '8', '4', '6']
['9', '5', '3', '8', '6', '4']
['9', '5', '4', '3', '6', '8']
['9', '5', '4', '3', '8', '6']
['9', '5', '4', '6', '3', '8']
['9', '5', '4', '6', '8', '3']
['9', '5', '4', '8', '3', '6']
['9', '5', '4', '8', '6', '3']
['9', '5', '6', '3', '4', '8']
['9', '5', '6', '3', '8', '4']
['9', '5', '6', '4', '3', '8']
['9', '5', '6', '4', '8', '3']
['9', '5', '6', '8', '3', '4']
['9', '5', '6', '8', '4', '3']
['9', '5', '8', '3', '4', '6']
['9', '5', '8', '3', '6', '4']
['9', '5', '8', '4', '3', '6']
['9', '5', '8', '4', '6', '3']
['9', '5', '8', '6', '3', '4']
['9', '5', '8', '6', '4', '3']
['9', '6', '3', '4', '5', '8']
['9', '6', '3', '4', '8', '5']
['9', '6', '3', '5', '4', '8']
['9', '6', '3', '5', '8', '4']
['9', '6', '3', '8', '4', '5']
['9', '6', '3', '8', '5', '4']
['9', '6', '4', '3', '5', '8']
['9', '6', '4', '3', '8', '5']
['9', '6', '4', '5', '3', '8']
['9', '6', '4', '5', '8', '3']
['9', '6', '4', '8', '3', '5']
['9', '6', '4', '8', '5', '3']
['9', '6', '5', '3', '4', '8']
['9', '6', '5', '3', '8', '4']
['9', '6', '5', '4', '3', '8']
['9', '6', '5', '4', '8', '3']
['9', '6', '5', '8', '3', '4']
['9', '6', '5', '8', '4', '3']
['9', '6', '8', '3', '4', '5']
['9', '6', '8', '3', '5', '4']
['9', '6', '8', '4', '3', '5']
['9', '6', '8', '4', '5', '3']
['9', '6', '8', '5', '3', '4']
['9', '6', '8', '5', '4', '3']
['9', '8', '3', '4', '5', '6']
['9', '8', '3', '4', '6', '5']
['9', '8', '3', '5', '4', '6']
['9', '8', '3', '5', '6', '4']
['9', '8', '3', '6', '4', '5']
['9', '8', '3', '6', '5', '4']
['9', '8', '4', '3', '5', '6']
['9', '8', '4', '3', '6', '5']
['9', '8', '4', '5', '3', '6']
['9', '8', '4', '5', '6', '3']
['9', '8', '4', '6', '3', '5']
['9', '8', '4', '6', '5', '3']
['9', '8', '5', '3', '4', '6']
['9', '8', '5', '3', '6', '4']
['9', '8', '5', '4', '3', '6']
注意,以下方法是不行的,反例是v=948635,k=64,此时3684找不到下一个后继3846,
所以不能从末尾往前扫交换4,而是应该交换6,即从后往前第一对正序对
class Solution:
def getMinSwaps(self, num: str, k: int) -> int:
def getnext(nums):
n = len(nums)
ok = False
for i in range(n-1,-1,-1):
if ok:
break
for j in range(i-1,-1,-1):
if ok:
break
if nums[j] < nums[i]:
num[j],num[i] = num[i],num[j]
ok = True
nums[j+1:n] = sorted(nums[j+1:n])
return nums
tmp = list(num)
num = list(num)
n = len(num)
ans = 0
for i in range(k):
num = getnext(num)
print(num)
for i in range(n):
if tmp[i] == num[i]:
continue
print(i)
pos = -1
for j in range(i+1,n):
if num[j] == tmp[i]:
pos = j
break
for j in range(pos,i,-1):
num[j],num[j-1] = num[j-1],num[j]
ans += 1
return ans
['9', '4', '8', '6', '5', '3'] ['9', '5', '3', '4', '6', '8'] ['9', '5', '3', '4', '8', '6'] ['9', '5', '3', '6', '4', '8'] ['9', '5', '3', '6', '8', '4'] ['9', '5', '4', '3', '6', '8'] ['9', '5', '4', '3', '8', '6'] ['9', '5', '4', '6', '3', '8'] ['9', '5', '4', '6', '8', '3'] ['9', '5', '4', '8', '3', '6'] ['9', '5', '4', '8', '6', '3'] ['9', '5', '6', '3', '4', '8'] ['9', '5', '6', '3', '8', '4'] ['9', '5', '6', '4', '3', '8'] ['9', '5', '6', '4', '8', '3'] ['9', '5', '6', '8', '3', '4'] ['9', '5', '6', '8', '4', '3'] ['9', '5', '8', '3', '4', '6'] ['9', '5', '8', '3', '6', '4'] ['9', '5', '8', '4', '3', '6'] ['9', '5', '8', '4', '6', '3'] ['9', '5', '8', '6', '3', '4'] ['9', '5', '8', '6', '4', '3'] ['9', '6', '3', '4', '5', '8'] ['9', '6', '3', '4', '8', '5'] ['9', '6', '3', '5', '4', '8'] ['9', '6', '3', '5', '8', '4'] ['9', '6', '4', '3', '5', '8'] ['9', '6', '4', '3', '8', '5'] ['9', '6', '4', '5', '3', '8'] ['9', '6', '4', '5', '8', '3'] ['9', '6', '4', '8', '3', '5'] ['9', '6', '4', '8', '5', '3'] ['9', '6', '5', '3', '4', '8'] ['9', '6', '5', '3', '8', '4'] ['9', '6', '5', '4', '3', '8'] ['9', '6', '5', '4', '8', '3'] ['9', '6', '5', '8', '3', '4'] ['9', '6', '5', '8', '4', '3'] ['9', '6', '8', '3', '4', '5'] ['9', '6', '8', '3', '5', '4'] ['9', '6', '8', '4', '3', '5'] ['9', '6', '8', '4', '5', '3'] ['9', '6', '8', '5', '3', '4'] ['9', '6', '8', '5', '4', '3'] ['9', '8', '3', '4', '5', '6'] ['9', '8', '3', '4', '6', '5'] ['9', '8', '3', '5', '4', '6'] ['9', '8', '3', '5', '6', '4'] ['9', '8', '4', '3', '5', '6'] ['9', '8', '4', '3', '6', '5'] ['9', '8', '4', '5', '3', '6'] ['9', '8', '4', '5', '6', '3'] ['9', '8', '4', '6', '3', '5'] ['9', '8', '4', '6', '5', '3'] ['9', '8', '5', '3', '4', '6'] ['9', '8', '5', '3', '6', '4'] ['9', '8', '5', '4', '3', '6'] ['9', '8', '5', '4', '6', '3'] ['9', '8', '5', '6', '3', '4'] ['9', '8', '5', '6', '4', '3'] ['9', '8', '6', '3', '4', '5'] ['9', '8', '6', '3', '5', '4'] ['9', '8', '6', '4', '3', '5']