zoukankan      html  css  js  c++  java
  • UVa 1262 (第k字典序) Password

    题意:

    给出两个6行5列的字母矩阵,一个密码满足:密码的第i个字母在两个字母矩阵的第i列均出现。

    然后找出字典序为k的密码,如果不存在输出NO

    分析:

    我们先统计分别在每一列均在两个矩阵出现的字母,然后从小到大排好序。

    对于第一个样例来说,我们得到ACDW、BOP、GMOX、AP、GSU

    则一共有4×3×4×2×3=288种密码,我们先计算这个数列的后缀积:288、72、24、6、3、1

    要确定第一个字母,如果1≤k≤72,则是A;如果73≤k≤144,则是C,以此类推。

    确定第二个字母是类似的,用k%72+1与24去比较。

    代码实现中,字典序是从0开始的。

     1 //#define DEBUG
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 char G[2][6][5], ans[6], select[6][5];
     6 int vis[2][26], hehe[6], cnt[5];
     7 
     8 int main()
     9 {
    10     //freopen("in.txt", "r", stdin);
    11 
    12     int T;
    13     scanf("%d", &T);
    14     hehe[5] = 1;
    15     while(T--)
    16     {
    17         memset(cnt, 0, sizeof(cnt));
    18         int k;
    19         scanf("%d", &k);
    20         k--;    //字典序标号从0开始
    21         for(int i = 0; i < 2; ++i)
    22             for(int j = 0; j < 6; ++j)
    23                 scanf("%s", G[i][j]);
    24 
    25         for(int i = 0; i < 5; ++i)
    26         {
    27             memset(vis, 0, sizeof(vis));
    28             for(int j = 0; j < 2; ++j)
    29                 for(int k = 0; k < 6; ++k)
    30                     vis[j][G[j][k][i]-'A'] = 1;
    31             for(int j = 0; j < 26; ++j)
    32                 if(vis[0][j] && vis[1][j])
    33                     select[i][cnt[i]++] = 'A' + j;
    34         }
    35 
    36         #ifdef DEBUG
    37         for(int i = 0; i < 5; ++i)
    38         {
    39             for(int j = 0; j < select[i].size(); ++j)
    40                 printf("%c", select[i][j]);
    41             puts("");
    42         }
    43         #endif // DEBUG
    44 
    45         for(int i = 4; i >= 0; --i)
    46             hehe[i] = cnt[i] * hehe[i+1];
    47         if(k >= hehe[0])
    48         {
    49             puts("NO");
    50             continue;
    51         }
    52         for(int i = 0; i < 5; ++i)
    53         {
    54             int m = k / hehe[i+1];
    55             ans[i] = select[i][m];
    56             k = k % hehe[i+1];
    57         }
    58         ans[5] = '';
    59 
    60         printf("%s
    ", ans);
    61     }
    62 
    63     return 0;
    64 }
    代码君一

    解法二:

    因为密码最多有65 = 7776种,所以可以按字典序从小到大枚举。

    思维难度小,写起来更快更对。

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 int k, cnt;
     5 char G[2][6][5], ans[6];
     6 
     7 bool dfs(int col)
     8 {
     9     if(col == 5)
    10     {
    11         if(++cnt == k)
    12         {
    13             ans[col] = '';
    14             printf("%s
    ", ans);
    15             return true;
    16         }
    17         return false;
    18     }
    19 
    20     bool vis[2][26];
    21     memset(vis, false, sizeof(vis));
    22     for(int i = 0; i < 2; ++i)
    23         for(int j = 0; j < 6; ++j)
    24             vis[i][G[i][j][col] - 'A'] = 1;
    25     for(int i = 0; i < 26; ++i)
    26         if(vis[0][i] && vis[1][i])
    27         {
    28             ans[col] = i + 'A';
    29             if(dfs(col+1)) return true;
    30         }
    31     return false;
    32 }
    33 
    34 int main()
    35 {
    36     //freopen("in.txt", "r", stdin);
    37     int T;
    38     scanf("%d", &T);
    39     while(T--)
    40     {
    41         scanf("%d", &k);
    42         for(int i = 0; i < 2; ++i)
    43             for(int j = 0; j < 6; ++j)
    44                 scanf("%s", G[i][j]);
    45 
    46         cnt = 0;
    47         if(!dfs(0)) puts("NO");
    48     }
    49 
    50     return 0;
    51 }
    代码君二
  • 相关阅读:
    深度剖析Reges.Match
    Python入门(一)
    SQL Server部分锁说明理解
    虚拟机Linux安装redis(一)
    transform matrix阅读后的理解
    小程序SKU规格选择
    React 学习记录(二)
    React 学习记录(一)
    在MVC里面使用Response.Redirect方法后记得返回EmptyResult——转载自PowerCoder
    Nodejs的安装随笔
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4175508.html
Copyright © 2011-2022 走看看