题意:
给出两个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; }