题解 UVA1262 【Password】
题目链接:Link
Solution
首先,先按列处理出所有合法的字母,按字典序排列。
注意!有可能会有相同的字母!
接下来,从左到右计算应该选那个字母(无解的情况预处理一下就行了)
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int T,k;
bool found[7][128];
char x;
vector<char> can[7];
int last[7];
int main()
{
#ifdef local
freopen("pro.in","r",stdin);
#endif
scanf("%d",&T);
while(T-->0)
{
memset(found,0,sizeof(found));
for(int i=1;i<=5;i++) can[i].clear();
cin>>k;
for(int i=1;i<=6;i++)
for(int j=1;j<=5;j++)
found[j][cin>>x,x]=1;
for(int i=1;i<=6;i++)
for(int j=1;j<=5;j++)
if(found[j][cin>>x,x])
{
can[j].push_back(x);
found[j][x]=0;
}
for(int i=1;i<=5;i++) sort(can[i].begin(),can[i].end());
last[5]=1;
for(int i=4;i>=0;i--) last[i]=last[i+1]*can[i+1].size();
if(k>last[0]) cout<<"NO"<<endl;
else
{
for(int i=1;i<=5;i++)
{
int j=ceil((double)k/last[i])-1;
/*
计算出该用哪个字母。
∵ 如果 last[i]*(j+1)>=k 则用当前字符
∴ 向上取整再减1就是下标。
*/
cout<<can[i][j];
k-=last[i]*j;
}
cout<<endl;
}
}
return 0;
}
本作品由happyZYM采用知识共享 署名-非商业性使用-相同方式共享 4.0 (CC BY-NC-SA 4.0) 国际许可协议(镜像(简单版)镜像(完整版))进行许可。
转载请注明出处:https://www.cnblogs.com/happyZYM/p/11379976.html (近乎)全文转载而非引用的请在文首添加出处链接。