【k进制 计数(?)】 Tavan 6.23测试COCI
样例:
9 2 3 7
po#olje#i
sol
znu
posoljeni
4 1 2 2
#rak
zm
zrak
之前的做法,由于
2
6
500
26^{500}
26500太大 所以
p
[
]
p[]
p[]会爆
数据比较小 有90分
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<string>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 505
#define LL long long
char s[MAXN],mb[MAXN][30];
int n,m,k,x,num;
LL p[MAXN];
int main()
{
//freopen("tavan.in","r",stdin);
//freopen("tavan.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&k,&x);
scanf("%s",s+1);
int cnt=0,sum=1;
for(int i=1;i<=m;i++)
{
scanf("%s",mb[i]+1);
sort(mb[i]+1,mb[i]+k+1);
//printf("%s\n",mb[i]+1);
}
p[1]=k;
for(int i=2;i<=m;i++)
p[i]=k*p[i-1];
//for(int i=1;i<=m;i++)
// printf("%d ",p[i]);
for(int i=1;i<=n;i++)
if(s[i]=='#')
{
++num;
if(num==m)
{
s[i]=mb[m][x];
break;
}
else
{
int tmp=x/p[m-num];
if(x%p[m-num]) tmp++;
//printf("%d\n",tmp);
s[i]=mb[num][tmp];
x=x-(tmp-1)*p[m-num];
/*int tmp=x/k;
x=x-tmp*k;
if()
if(x%k) tmp++;
s[i]=mb[num][tmp];*/
}
}
puts(s+1);
return 0;
}
那么就反其道而行之
从最后一位倒着搞回来
有点像k进制(实际上就是k进制吧
也要注意细节
尤其是刚好整除时的情况
代码中的注释很详细了 (注释之述备矣
//正难则反 倒过来统计
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<string>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 505
#define LL long long
char s[MAXN],mb[MAXN][30];
int n,m,k,x,num;
LL p[MAXN];
int main()
{
//freopen("tavan.in","r",stdin);
//freopen("tavan.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&k,&x);
scanf("%s",s+1);
int cnt=0,sum=1;
for(int i=1;i<=m;i++)
{
scanf("%s",mb[i]+1);
sort(mb[i]+1,mb[i]+k+1);
}
for(int i=n;i>=1;i--)
{
if(s[i]=='#')
{
int tmp=x%k;
if(tmp==0) tmp=k;
//找规律 周期问题 最后一位取第几个是取决于x%k的
s[i]=mb[m][tmp];
m--;
//x/=k 是把当前已经决定了的这一位抛开 单看剩下的位数 字典序应该排在哪里(画个图大概体会一下
if(x%k==0) x/=k;
//如果能刚好整除 就恰好是那一组的最后一个
else x/=k,x++;
//如果不能整除,除法是下取整的,就跑到了上一组去,所以要加回来
//整除的商是上一组的字典序 而余数就是在这一位取的值 就是比上一位多多少 这肯定是要算到后一组去的
//这里的组数指的是除去当前这一位 进行排列的结果 可以看作每一组有k个 详细见下图
}
}
puts(s+1);
return 0;
}
然后我最前面考场上的90分做法 看到有个大佬似乎有点像
但没有怎么看懂
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
int len,n,psi,rnk,nsur;
string wrd;
long long powp[505];
char sur[505];
int main(){
freopen("tavan.in","r",stdin);
freopen("tavan.out","w",stdout);
scanf("%d%d%d%d",&len,&n,&psi,&rnk);
powp[0]=1;
for(int i=1;i<=500;i++){
powp[i]=powp[i-1]*psi;
if(powp[i]>rnk) powp[i]=1000000005;
}
cin>>wrd;
for(int i=1;i<=n;i++){
string abl;
cin>>abl;
sort(abl.begin(),abl.end());
int f=(rnk-1)/powp[n-i];
rnk-=f*powp[n-i];
sur[++nsur]=abl[f];
}
for(int i=0,j=1;i<len;i++){
if(wrd[i]=='#') printf("%c",sur[j++]);
else printf("%c",wrd[i]);
}
printf("\n");
return 0;
}
但现下也还未决心实践,正在研究而且推敲
玄学之事,难言之矣,这也只得姑且置之弗论了
转载请注明出处,有疑问欢迎探讨
博主邮箱 2775182058@qq.com