思路
这道题其实就是一个暴力模拟,但是细节极其的多,很**。
我们可以把每个奶牛编码为一个混进制,这样如果我们要获取第 $x$ 个,我们就可以直接把 $x$ 从十进制转换为混进制,然后记录每一位的每个数对应的单词,就可以得出答案了。
注意由于题目给定了不能出现的奶牛,那么我们需要对输入的 $k$ 进行处理,算出 $k$ 实际上时编号为多少的奶牛。
代码
#include <bits/stdc++.h>
//#define int long long
using namespace std;
/*
*/
int n, k;
string s[105][110], ss[110];
int a[105][110], b[1005], cnt[1000005], c[1005];
int t = 0, ans[1000005], tot, anss[1000005];
map <string, int> mp[110];
map <int, string> mpp[110];
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
for (int i = 1; i <= n; i ++) {
int x = 0;
while (cin >> s[i][++x]) {
if (s[i][x] == "cow.")
break;
}
t = x;
for (int j = 1; j <= x; j ++) {
// cout << s[i][j] << " ";
mp[j][s[i][j]] = 1;
}
// cout << "\n";
}
for (int i = 1; i <= t; i ++) {
for (auto j = mp[i].begin(); j != mp[i].end(); j ++) {
cnt[i] ++;
mp[i][j -> first] = cnt[i];
}
}
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= t; j ++) {
a[i][j] = mp[j][s[i][j]];
mpp[j][mp[j][s[i][j]]] = s[i][j];
// cout << a[i][j] << " ";
}
// cout << "\n";
}
c[t + 1] = 1;
for (int i = t; i >= 1; i --) {
c[i] = c[i + 1] * cnt[i];
}
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= t; j ++) {
b[i] += (a[i][j] - 1) * c[j + 1];
}
}
sort(b + 1, b + n + 1);
int pos = 0;
k --;
for (int i = 1; i <= n; i ++) {
if (b[i] > k + pos) {
break;
}
pos = i;
}
k += pos;
// k--;
int cntt = t;
// cout << k << "\n";
while (k) {
cntt --;
ans[++tot] = k % cnt[cntt];
// cout << k << " " << cnt[cntt] << "\n";
anss[tot] = cntt;
k /= cnt[cntt];
}
// cout << tot << "\n";
// for (int i = 1; i <= tot; i ++)
// cout << ans[i] << " ";
// cout << "\n";
for (int i = 1; i <= t - 5 - tot; i ++) {
cout << mpp[4 + i][1] << " ";
}
for (int i = tot; i >= 1; i --) {
ss[i] = mpp[anss[i]][ans[i] + 1];
cout << ss[i] << " ";
}
return 0;
}