zoukankan      html  css  js  c++  java
  • 单词矩阵/贰五语言

             problem   codevs 洛谷                                     

    题意:

        对于包含字母A到Y各一次的单词S,将其从上到下从左到右写在一个5*5的矩阵中,如单
        词ADJPTBEKQUCGLRVFINSWHMOXY写出来如下:
        A D J P T
        B E K Q U
        C G L R V
        F I N S W
        H M O X Y
        若该矩阵满足每一行每一列的字母都是字典序递增的则称S为优美的,如上述单词就是
        优美的,而ADJPTBEGQUCKLRVFINSWHMOXY则不是(第二列不满足要求)。
        Your Task
        将所有优美的单词按字典序列出,从小到大编号1,2,……
        请你完成以下两种任务:
        1. 给定一个优美的单词,求其编号。
        2. 给定一个编号,求对应的优美的单词。

    输入描述 Input Description

        第一行一个字母,W表示任务1,N表示任务2
        若是任务1,第二行是一个优美的单词,否则第二行是一个正整数,表示某个优美的单
        词的编号,保证该数不超过优美的单词的总数

    输出描述 Output Description

        一行,若是任务1,输出对应编号,否则输出对应的优美的单词 

    思路:

        试图找规律 无果  所以就搜索啦 (在做之前就知道是一道搜索题qwq)

                   从小到达枚举字母来填方格时

        对于每一行 左边的必须比右边先填(保证从左至右递增)  

           对于每一列 上面的必须比下面先填(保证从上至下递增)

        So dfs(a,b,c,d,e,now)   a表示第一行已经填了几个 b,c,d,e 同推  now表示现在要填第几个字母了(1表示A etc.)

                   带上记忆化搜索

        那么就是f[a][b][c][d][e]表示第一行填了a个,第二行填b个,第三行填c个,第四行填d个,第5行填e个的满足题意的总方案数

        现在我们具体来看两个问题:

                   1.给定序列求编号

        就是求字典序比它小的合法序列个数再加1(加上它自己)

        枚举第1-25位上的数的字母 每一位都不能超过题目给定序列对应位置上的字母 (不能等于!)

                   举个栗子:

        我们要知道以BE开头的合法序列个数 那么搜第一位为A的序列列数

        然后搜第一二位为BE的合法序列数 而不是搜第一位为B的合法序列数

        然后把搜索到的方案数都加起来 输出答案记得加上1

          2.给定编号求序列

        同从小到大枚举第1-25位上的数字

        假设 我们求第90个序列  现在枚举第二位(第一位必为A) 第二位为B时 有方案80种 ;为C时 有方案30种 

        那么要求的第90个序列的第二位一定为 C (方案总数刚好大于90)   

        以此类推 一位一位地确定下去

          

                  

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 using namespace std;
     6 int f[6][6][6][6][6],map[30],ans;
     7 bool ck(int a,int b) {return (!map[a])||(map[a]==b);}
     8 int dfs(int a,int b,int c,int d,int e,int now)
     9 {
    10   if(now==26) return 1;
    11   int &tmp=f[a-1][b-1][c-1][d-1][e-1];
    12   if(tmp) return tmp;
    13   if(a<=5 && ck(a,now)) tmp+=dfs(a+1,b,c,d,e,now+1);
    14   if(b<a && ck(b+5,now)) tmp+=dfs(a,b+1,c,d,e,now+1);
    15   if(c<b && ck(c+10,now)) tmp+=dfs(a,b,c+1,d,e,now+1);
    16   if(d<c && ck(d+15,now)) tmp+=dfs(a,b,c,d+1,e,now+1);
    17   if(e<d && ck(e+20,now)) tmp+=dfs(a,b,c,d,e+1,now+1);
    18   return tmp;
    19 }
    20 int main()
    21 {
    22   char tp;scanf("%c",&tp);
    23   if(tp=='W') {
    24     string s;cin>>s;
    25     for(register int i=1;i<=25;i++)
    26       for(map[i]=1;map[i]<s[i-1]-'A'+1;map[i]++) {
    27     memset(f,0,sizeof(f));
    28     ans+=dfs(1,1,1,1,1,1);
    29       }
    30     printf("%d",ans+1); //要+1
    31   }
    32   else {
    33     int n;scanf("%d",&n);
    34     for(register int i=1;i<=25;i++)
    35       for(map[i]=1;map[i]<25;map[i]++)
    36     {
    37       memset(f,0,sizeof(f));
    38       int tmp=dfs(1,1,1,1,1,1);
    39       if(tmp>=n) break ;
    40       n-=tmp; //注意这里
    41     }
    42     for(register int i=1;i<=25;i++) printf("%c",map[i]-1+'A');
    43   }
    44   return 0;
    45 }
    View Code
    光伴随的阴影
  • 相关阅读:
    Java Gradle
    C/C++ C++11新特性
    C/C++ C++11原子类型和内存序
    基于流的编程(Flow-Based Programming)
    算法和数据结构 筛法求素数
    数据库 悲观锁和乐观锁
    数据库 事务隔离级别
    Serverless 的 AI 写诗,程序员浪漫起来谁能顶得住啊!
    亮点前瞻 | 首届 ServerlesssDays · China 大会议程发布
    腾讯云云函数 SCF Node.js Runtime 最佳实践
  • 原文地址:https://www.cnblogs.com/forward777/p/10307268.html
Copyright © 2011-2022 走看看