Pro
Sol
奇怪的字符串
样例很棒啊。
#include<iostream>
#include<cstdio>
using namespace std;
int n , k , flag = 0;
int main() {
freopen("str.in","r",stdin);
freopen("str.out","w",stdout);
scanf("%d%d",&n,&k);
if(k>n||(k==1&&n!=1)) {
printf("-1");
return 0;
}
if(n==k) {
for(int i=1; i<=k; i++)
printf("%c",i+'a'-1);
return 0;
}
for(int i=1; i<=(n-k+2); i++) {
if(flag) {
flag = 0;
printf("b");
} else {
flag = 1;
printf("a");
}
}
for(int i=1; i<=k-2; i++)
printf("%c",i+'a'+1);
return 0;
}
排列
CF原题……不过貌似这道题(相对于原题)变水了。
暴力40分
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n , p1 , p2 , jc[12];
void init() {
jc[0] = 1;
for(int i=1; i<=n; i++)
jc[i] = jc[i-1]*i;
}
void sol1() {
int num[15] , cnt[15];
memset(cnt , 0 , sizeof(cnt));
for(int i=1; i<=n; i++)
scanf("%d",&num[i]);
for(int i=1; i<=n; i++)
for(int j=1; j<i; j++)
if(num[j]<num[i])
cnt[i]++;
if(num[1]>0)
p1 += jc[n-1]*num[1];
for(int i=2; i<n; i++)
p1 += jc[n-i]*(num[i]-cnt[i]);
}
void sol2() {
int num[15] , cnt[15];
memset(cnt , 0 , sizeof(cnt));
for(int i=1; i<=n; i++)
scanf("%d",&num[i]);
for(int i=1; i<=n; i++)
for(int j=1; j<i; j++)
if(num[j]<num[i])
cnt[i]++;
if(num[1]>0)
p2 += jc[n-1]*num[1];
for(int i=2; i<n; i++)
p2 += jc[n-i]*(num[i]-cnt[i]);
}
void sol3(int x) {
int vis[15] , pot = x/jc[n-1] , crt = 0;
memset(vis , 0 , sizeof(vis));
double temp = x*1.0/jc[n-1];
if(temp==(int)temp) {
x -= (pot-1)*jc[n-1];
printf("%d ",pot-1);
vis[pot-1] = 1;
}
else {
x -= pot*jc[n-1];
printf("%d ",pot);
vis[pot] = 1;
}
for(int i=2; i<n; i++) {
int top = 0 , use = 0;
for(int j=0; j<n; j++) {
if(vis[j]) {
use++;
continue;
}
top += jc[n-i];
if(top>=x) {
printf("%d ",j);
vis[j] = 1;
x -= jc[n-i]*(j-use);
break;
}
}
}
for(int i=0; i<n; i++) {
if(vis[i])
continue;
crt++;
if(crt==x) {
printf("%d",i);
return ;
}
}
}
int main() {
freopen("perm.in","r",stdin);
freopen("perm.out","w",stdout);
scanf("%d",&n);
init();
sol1();
sol2();
sol3((p1+p2)%jc[n]+1);
return 0;
}
康托展开(模拟题中能A,CF原题会T)
#include<iostream>
#include<cstdio>
using namespace std;
long long n , a[200005] , b[200005] , ak[200005] , bk[200005] , ck[200005] , vis[200005];
int main() {
freopen("perm.in","r",stdin);
freopen("perm.out","w",stdout);
scanf("%lld",&n);
for(long long i=1; i<=n; i++)
scanf("%lld",&a[i]);
for(long long i=1; i<=n; i++)
scanf("%lld",&b[i]);
for(long long i=1; i<=n; i++)
for(long long j=i+1; j<=n; j++) {
if(a[j]<a[i])
ak[i]++;
if(b[j]<b[i])
bk[i]++;
}
for(long long i=n-1; i>=1; i--) {
ck[i] += ak[i] + bk[i];
ck[i-1] += ck[i]/(n-i+1);
ck[i] = ck[i] % (n-i+1);
}
for(long long i=1; i<=n; i++) {
ck[i]++;
long long cnt = 0;
for(long long j=1; j<=n; j++) {
if(!vis[j])
cnt++;
if(cnt==ck[i]) {
printf("%lld ",j-1);
vis[j] = 1;
break;
}
}
}
return 0;
}
CF中正解是:树状数组+二分 or 平衡树 什么的……
分雕塑
15年APIO原题。
数位DP,待更。