10-8 uva1262密码

题意:有两个图,每一列都存在的字母选作密码,就第k大的密码

思路:
找出各个位置上的密码,

假设:

第1个字母只能是{A,C,D,W},

第2个字母只能是{B,O,P},

第3个字母只能是{G,M,O,X},

第4个字母只能是{A,P},

第5个字母只能是{G,S,U}。
不管第1个字母是多少,后4个字母都有3*4*2*3=72种可能,因此当k≤72时,第1个字母
是A,当72<k≤144时第1个字母是C,如此等等。再用同样的方法确定第2,3,4,5个字母即
可。


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

char tmap[2][20][10];
vector<char>mp[10];
int vis[2][20][30];//第i个图,第j列的x字母

int num[10];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int k;
        scanf("%d",&k);
        memset(vis,0,sizeof(vis));
        for(int j = 0; j < 2; j++)
            for(int i = 0; i < 6; i ++)
                scanf("%s",tmap[j][i]);
        for(int i=0; i<5; ++i)
            for(int j=0; j<6; ++j)
            {
                vis[0][i][tmap[0][j][i]-'A']=true;
                vis[1][i][tmap[1][j][i]-'A']=true;
            }
        for(int i = 0;i < 5;i++)
            mp[i].clear();
        for(int i = 0;i < 5;i++)
        {
            for(int j = 0;j <= 26;j++)
            {
                if( vis[0][i][j] && vis[1][i][j])
                    mp[i].push_back(j + 'A');
            }
        }
        num[5] = 1;
        for(int i = 4; i >= 0; i--)
        {
            num[i] = num[i+1] * (int)mp[i].size();
        }
        if(k > num[0])
            printf("NO\n");
        else
        {
            k--;
            for(int i = 0; i < 5; i++)
            {
                putchar(mp[i][k/num[i+1]]);
                k %= num[i+1];
            }
            printf("\n");
        }
    }
    return 0;
}

  




 

posted @ 2015-10-10 20:00  Przz  阅读(157)  评论(0编辑  收藏  举报