题意:
给出两个6行5列的字母矩阵,一个密码满足:密码的第i个字母在两个字母矩阵的第i列均出现。
然后找出字典序为k的密码,如果不存在输出NO
思路分析 :
暴力枚举就可以,但是有两个细节,每一列的字母必须是同时出现在两个表中的,并且要保证相同的字母出现多次均按照一次计算
代码示例 :
#define ll long long
const ll maxn = 1e6+5;
const ll mod = 1e9+7;
const double eps = 1e-9;
const double pi = acos(-1.0);
const ll inf = 0x3f3f3f3f;
ll n;
char a[10][10], b[10][10];
map<char, ll>mp;
vector<char>ve[10];
ll num[10];
void init(){
for(ll i = 1; i <= 5; i++) ve[i].clear();
memset(num, 0, sizeof(num));
for(ll i = 1; i <= 5; i++){
mp.clear();
for(ll j = 1; j <= 6; j++){
mp[a[j][i]]++;
}
for(ll j = 1; j <= 6; j++){
if (mp[b[j][i]] > 0) {
ve[i].push_back(b[j][i]);
mp[b[j][i]] = 0;
num[i]++;
}
}
}
for(ll i = 1; i <= 5; i++) sort(ve[i].begin(), ve[i].end());
}
void fun(ll k, ll x){
if (k == 6) return;
ll s = 1;
for(ll i = k+1; i <= 5; i++){
s *= num[i];
}
ll sum = s;
for(ll i = 0; i < num[k]; i++){
if (sum >= x) {
printf("%c", ve[k][i]);
fun(k+1, x-i*s);
return;
}
sum += s;
}
}
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
ll t;
cin >> t;
while(t--){
scanf("%lld", &n);
for(ll i = 1; i <= 6; i++){
scanf("%s", a[i]+1);
}
for(ll i = 1; i <= 6; i++){
scanf("%s", b[i]+1);
}
init();
ll sum = 1;
for(ll i = 1; i <= 5; i++) sum *= num[i];
if (sum < n) {printf("NO
"); continue;}
fun(1, n);
printf("
");
}
return 0;
}