模拟赛的题,内容主要考察的是字符串操作,字典序,和类似于k进制的转换,有兴趣的同学可以来看看。
题目真的是又臭又长。
#3369. Tavan
内存限制:32 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:文本比较
上传者: cqbzgm
题目描述
小 Zeljko 一直在阁楼里读他奶奶的旧信,并且发现了一个长度为 N 的单词。 不幸的是,由于溢出的墨水,他不知道单词的内容。他把看不清的 M 个字母每 个字母都用一个字符’#‘替换后,在一张纸上重写了这个词。他把那张纸递给 了他的奶奶,对于每个看不清的字母,奶奶给了他 K 个不同的可能。在那之后, Zeljko 在笔记本中写下了所有可能的单词,并决定仔细查看他们的属性,以确 定原始单词是什么。在看到笔记本上写下的单词后,他的奶奶意识到他们正在 寻找的是按字典序排列的第 X 个单词。Zeljko 在他们学校学习字母表的那天生 病了,所以他要求你帮助他确定原来的单词。 输入 第一行输入包含整数 N,M,K 和 X(1≤N≤500,1≤M≤N,1≤K≤26,1≤X≤ 1e9)。分别表示单词的长度,看不清的字母的数量,奶奶给出的字母的数量和 原单词是字典序的第几个。 第二行输入包含一个长度为 N 的字符串,由小写英文字母和字符’#‘组成。 表示 Zeljko 找到的单词,其中字符’#'表示看不清的字母。 接下来 M 行中的每一行包含一个长度为 K 的字符串,由 K 个不同的小写英文 字母组成。第 2+i 行的 K 个字母表示第 i 个看不清的 保证 X 总是小于等于能构造出的单词的总数。输入格式
第一行输入包含整数 N,M,K 和 X(1≤N≤500,1≤M≤N,1≤K≤26,1≤X≤ 1e9)。分别表示单词的长度,看不清的字母的数量,奶奶给出的字母的数量和 原单词是字典序的第几个。 第二行输入包含一个长度为 N 的字符串,由小写英文字母和字符’#‘组成。 表示 Zeljko 找到的单词,其中字符’#'表示看不清的字母。 接下来 M 行中的每一行包含一个长度为 K 的字符串,由 K 个不同的小写英文 字母组成。第 2+i 行的 K 个字母表示第 i 个看不清的字母的 K 种可能。 保证 X 总是小于等于能构造出的单词的总数。输出格式
输出一个字符串。表示原本的单词。样例
样例输入
9 2 3 7
po#olje#i
sol
znu
样例输出
posoljeni
数据范围与提示
对于 30%的数据,M=1 并且 K=3。 对于另外 30%的数据,M=1。
可能题目描述的不清楚,我来大致介绍一下题意。
给出一个字符串,"#“的位置可以由给出的几个字母来替换,比如第一个井号就可以是"s”,“o"和"l”,第二个井号就可以是"z",“n"和"u”。
这样这个字符串就有
3
2
3^2
32(题目中
M
K
M^K
MK)种可能的形态,将这
M
K
M^K
MK种情况排列,答案便是其中的第X个。
所以我们可以将字符串简化成K个井号,因为其它的字符都是固定的,对字典序的排列没有影响。
我们只需要将每个井号可能的字母从小到大排序,那么便可以得到:
l
,
o
,
s
l,o,s
l,o,s和
n
,
u
,
z
n,u,z
n,u,z,因为每个井号有k种情况,那么只需要将
X
−
1
X-1
X−1(因为我们要给第一位留个位置)转换为
K
K
K进制。样例中对应的便是
20
20
20,对应字母的情况就是
31
31
31,也就是
l
,
o
,
s
l,o,s
l,o,s的第三个字母和
n
,
u
,
z
n,u,z
n,u,z的第一个字母。
k进制的转换这里不详讲,详细见代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#define N 5005
#define LL long long
string a;
LL n,m,k,x,T=1,ans[N];
char A[N][N];
int main() {
cin>>n>>m>>k>>x;
cin>>a;
for(LL i=1;i<=m;i++) {
LL P[N];
for(LL j=0;j<k;j++) cin>>A[i][j];//排序
for(LL j=0;j<k;j++) P[j]=A[i][j];
sort(P,P+k);
for(LL j=0;j<k;j++) A[i][j]=(char)P[j];
}
LL cnt=0,x1=x-1;
for(LL i=m;i>=1;i--) {//k进制转换
ans[i]=x1%k;
x1/=k;
}
for(LL i=0;i<a.length();i++) {//输出答案
if(a[i]=='#') {
cnt++;
cout<<A[cnt][ans[cnt]];
}
else cout<<a[i];
}
}