mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-08-21 18:52:07 +00:00
152 lines
4.5 KiB
C++
152 lines
4.5 KiB
C++
#include <iostream>
|
||
#include <vector>
|
||
using namespace std;
|
||
|
||
typedef long long ll; // 定义长整型别名,用于处理大数
|
||
|
||
int main() {
|
||
ios::sync_with_stdio(false);
|
||
cin.tie(0); // 优化输入输出速度
|
||
|
||
int k;
|
||
cin >> k; // 读取数字集合大小
|
||
vector<int> d(k); // 存储数字集合
|
||
for (int i = 0; i < k; i++) {
|
||
cin >> d[i]; // 读取数字集合元素
|
||
}
|
||
|
||
// 检查数字集合是否包含0
|
||
bool has_zero = (d[0] == 0);
|
||
// 计算首位可用数字数量(首位不能为0)
|
||
int m = has_zero ? k - 1 : k;
|
||
|
||
// 创建首位可用数字数组
|
||
vector<int> arr;
|
||
if (has_zero) {
|
||
// 如果含0,首位使用除0外的其他数字
|
||
arr = vector<int>(d.begin() + 1, d.end());
|
||
} else {
|
||
// 如果不含0,所有数字都可用于首位
|
||
arr = d;
|
||
}
|
||
|
||
// 存储各长度幸运数的数量
|
||
vector<ll> cnt;
|
||
// 存储幸运数数量的前缀和
|
||
vector<ll> prefix;
|
||
ll total = 0; // 累计幸运数总数
|
||
int max_len = 0; // 最大长度
|
||
|
||
// 计算各长度幸运数的数量
|
||
for (int len = 1; ; len++) {
|
||
ll count_this; // 当前长度的幸运数数量
|
||
|
||
if (len == 1) {
|
||
// 长度为1:只有首位数字
|
||
count_this = m;
|
||
} else {
|
||
count_this = m; // 首位有m种选择
|
||
// 计算剩余len-1位的组合数
|
||
for (int i = 1; i < len; i++) {
|
||
// 防止溢出,超过10^18时设为极大值
|
||
if (count_this > 1000000000000000000LL / k) {
|
||
count_this = 1000000000000000001LL;
|
||
break;
|
||
}
|
||
count_this = count_this * k; // 每增加一位,数量乘以k
|
||
}
|
||
// 再次检查溢出
|
||
if (count_this > 1000000000000000000LL) {
|
||
count_this = 1000000000000000001LL;
|
||
}
|
||
}
|
||
|
||
// 更新总数
|
||
total += count_this;
|
||
// 防止总数溢出
|
||
if (total > 1000000000000000000LL) {
|
||
total = 1000000000000000001LL;
|
||
}
|
||
|
||
// 存储当前长度数量和前缀和
|
||
cnt.push_back(count_this);
|
||
prefix.push_back(total);
|
||
max_len++; // 增加长度计数
|
||
|
||
// 当总数超过10^18时停止计算
|
||
if (total >= 1000000000000000000LL) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
int q;
|
||
cin >> q; // 读取查询数量
|
||
while (q--) {
|
||
ll x;
|
||
cin >> x; // 读取查询的序号
|
||
|
||
ll prev = 0; // 存储当前长度之前的所有幸运数数量
|
||
int cur_len = -1; // 存储目标幸运数的长度
|
||
|
||
// 查找目标幸运数所在长度区间
|
||
for (int i = 0; i < max_len; i++) {
|
||
if (x <= prefix[i]) {
|
||
cur_len = i + 1; // 确定长度
|
||
break;
|
||
}
|
||
prev = prefix[i]; // 更新前缀和
|
||
}
|
||
|
||
// 处理极端情况(理论上不会发生)
|
||
if (cur_len == -1) {
|
||
cur_len = max_len;
|
||
prev = prefix.back() - cnt.back();
|
||
}
|
||
|
||
// 计算在当前长度组内的位置
|
||
ll pos = x - prev;
|
||
int r = cur_len - 1; // 剩余位数(除首位外)
|
||
|
||
// 计算剩余位数的基数(k^(r))
|
||
ll base_val = 1;
|
||
if (r > 0) {
|
||
for (int i = 0; i < r; i++) {
|
||
// 防止溢出
|
||
if (base_val > 1000000000000000000LL / k) {
|
||
base_val = 1000000000000000001LL;
|
||
break;
|
||
}
|
||
base_val = base_val * k;
|
||
}
|
||
// 再次检查溢出
|
||
if (base_val > 1000000000000000000LL) {
|
||
base_val = 1000000000000000001LL;
|
||
}
|
||
}
|
||
|
||
// 计算首位在arr中的索引
|
||
ll idx0 = (pos - 1) / base_val;
|
||
cout << arr[idx0]; // 输出首位数字
|
||
|
||
// 处理剩余位数
|
||
if (r > 0) {
|
||
ll rem = (pos - 1) % base_val; // 剩余部分的位置
|
||
vector<int> digits(r, 0); // 存储各位数字索引
|
||
|
||
// 将rem转换为k进制表示
|
||
for (int i = 0; i < r; i++) {
|
||
digits[r - 1 - i] = rem % k; // 从低位到高位存储
|
||
rem /= k;
|
||
}
|
||
|
||
// 输出剩余位数的数字
|
||
for (int i = 0; i < r; i++) {
|
||
cout << d[digits[i]]; // 输出对应数字
|
||
}
|
||
}
|
||
cout << '\n'; // 换行
|
||
}
|
||
|
||
return 0;
|
||
}
|