您的位置:首页 > 其它

Noip模拟题解题报告

2018-10-17 11:35 232 查看

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
+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,待更。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: