codeforces 513B1 Permutations
大意:求解第K个排列,且排列满足 的值尽可能大。 1 ≤ n ≤ 8
分析:数据量小,暴力解决。第K个排列和next_permutation相关
codeforces 513 B2. Permutations
分析:数据量小,暴力解决。第K个排列和next_permutation相关
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[10];
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k)){
int score=0;
for(int i=1;i<=n;i++){
score+=i*(n+1-i);
}
for(int i=0;i<n;i++){
a[i]=i+1;
}
int cnt=1;
while(cnt!=k){
next_permutation(a,a+n);
int temp=0;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int minm=n;
for(int k=i;k<=j;k++){
minm=min(minm,a[k]);
}
temp+=minm;
}
}
if(temp==score) cnt++;
}
for(int i=0;i<n-1;i++){
printf("%d ",a[i]);
}
printf("%d\n",a[n-1]);
}
return 0;
}
codeforces 513 B2. Permutations
大意:和上一个题题意一样,不过数据范围是 1——50
分析:现在不能用暴力做了。但是分析可以得到,小数必然需要在两端,大数在中间才能使得最后的函数值尽可能大。
所以现在就是安排N个数字成一个满足条件的排列。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
int a[55];
LL power(LL a,LL p){
LL ans=1;
while(p){
if(p&1) ans=ans*a;
a=a*a;
p>>=1;
}
return ans;
}
int main()
{
LL n,k;
while(~scanf("%I64d%I64d",&n,&k)){
int p1=0;
int p2=n-1;
for(int i=1;i<=n;i++){
LL perm=power(2,n-i);
if(i==n){
a[p1++]=i;
continue;
}
LL perm2=perm/2;
if(k<perm&&k>perm2){
a[p2--]=i;
k-=perm2;
}
else if(k<perm) a[p1++]=i;
else if(k>perm) {
k-=perm;
a[p2--]=i;
}
else {
a[p2--]=i;
k-=perm2;
}
}
for(int i=0;i<n-1;i++){
printf("%d ",a[i]);
}
printf("%d\n",a[n-1]);
}
return 0;
}