• USACO 5.5 Twofive


    Twofive
    IOI 2001

    In order to teach her young calvess the order of the letters in the alphabet, Bessie has come up with a game to play with them. The calves are given a 5 x 5 grid on which they can put the letters 'A'-'Y', but the one rule is that all the letters going across the columns and down the rows must be in the order they appear in the alphabet.

    There are a huge number of possible grids, so Bessie decides that they will be named by the string of letters that is given by reading across each row, going down the rows. For example, the grid: 

     
         A B C D E
         F G H I J
         K L M N O
         P Q R S T 
         U V W X Y
    


    would have the name ABCDEFGHIJKLMNOPQRSTUVWXY, which is coincidentally the first possible grid when the entire set of grids is ordered alphabetically. The second grid that meets this requirement is ABCDEFGHIJKLMNOPQRSUTVWXY, which is formed by switching the 'T' and 'U' in the above grid.

    Help the calves gain bragging rights. Given a number, M, find which string is Mth in the list of all possible grids when they are sorted alphabetically, and, given a string of letters, find out what number the corresponding grid is in the list of all possible grids.

    PROGRAM NAME: twofive

    INPUT FORMAT

    The first input line contains one of two letters, either an 'N' or a 'W'.

    If the first input line contains an 'N', the second line will contain an integer, M, that corresponds to the number of a valid grid. If the first line contains a 'W', the second line will contain a string of 25 letters, which represents a valid grid.

    OUTPUT FORMAT

    If the input contained the number of a valid grid (first line 'N'), the output should contain a string of 25 letters on a line, which corresponds to the Mth grid in the sorted list of all possible grids.

    If the input contained a string of letters indicating a grid (first line 'W'), the output should contain a single integer on a line, which corresponds to the number of the given grid in the list of all possible grids.

    SAMPLE INPUT #1 (file twofive.in)

    N
    2
    

    SAMPLE OUTPUT #1 (file twofive.out)

    ABCDEFGHIJKLMNOPQRSUTVWXY
    

    SAMPLE INPUT #2 (file twofive.in)

    W
    ABCDEFGHIJKLMNOPQRSUTVWXY
    

    SAMPLE OUTPUT #2 (file twofive.out)

    2
    

    ——————————————————————————————————题解

    越刷神题越多……

    这道题的思路和介个差不多虽然这道没有做出来

    一开始的思路就是赤裸裸的暴力然后map,结果跑不动qwq

    然后我要开始写一份详细的解题报告了

    如果是编码转单词:

    初始计数器s=0,编码为d

    计算AB开头所有的单词x,如果s+x>=d,那么我们可以发现AB开头的所有单词囊括了所有1-d的单词,所以第二位就是B

    如果s+x<d,那么1-d中包含了AB开头所有单词,那么我们继续枚举下一位,直到满足s+x>=d

    由此可以计算出这个单词

    如果是单词转编码:

    初始计数器s=0

    假如一个串AFKPUBGLQVCHMRWDINSXEJOTY

    这个单词之前一定有AB,AC,AD,AE开头的所有单词,用s累加上他们的和

    然后处理AFB开头的所有单词(处理出来会是0)AFC……AFJ开头的所有单词和,以下位同理

    最后s+1就是我们想要的解

    那么我们如何计算一个固定前缀开头所有单词的和,用记忆化搜索f[a][b][c][d][e]表示第一行有a个字符,第二行有b个字符,第三行有c个字符,第四行有d个字符,第五行有e个字符,其中这些字符是前a+b+c+d+e个字符,且a->e递减,我们再记一个ans序列是我们固定好的前缀,如果搜索到该位置要往里面填一个字母,这个位置没有字母或者这个位置的字母正好是我们ans里记录的,我们就填,否则跳过

    这个记忆化搜索的边界条件是搜满了之后填1

    据说用5位六进制数可以让程序变得美观然而我没有

      1 /*
      2 ID: ivorysi
      3 LANG: C++
      4 PROG: twofive
      5 */
      6 #include <iostream>
      7 #include <cstdio>
      8 #include <cstring>
      9 #include <algorithm>
     10 #include <queue>
     11 #include <set>
     12 #include <vector>
     13 #include <string.h>
     14 #include <cmath>
     15 #include <stack>
     16 #include <map>
     17 #define siji(i,x,y) for(int i=(x);i<=(y);++i)
     18 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
     19 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
     20 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
     21 #define inf 0x5f5f5f5f
     22 #define ivorysi
     23 #define mo 97797977
     24 #define hash 974711
     25 #define base 47
     26 #define pss pair<string,string>
     27 #define MAXN 5000
     28 #define fi first
     29 #define se second
     30 #define pii pair<int,int>
     31 #define esp 1e-8
     32 typedef long long ll;
     33 using namespace std;
     34 ll f[8][8][8][8][8],d,s;
     35 int used[30];
     36 char ans[30],str[30];
     37 void init() {
     38     siji(i,0,5) {
     39         siji(j,0,5) {
     40             siji(k,0,5) {
     41                 siji(z,0,5) {
     42                     siji(o,0,5) {
     43                         f[i][j][k][z][o]=-1;
     44                     }
     45                 }
     46             }
     47         }
     48     }
     49 }
     50 int dfs(int a1,int a2,int a3,int a4,int a5,char t) {
     51     if(f[a1][a2][a3][a4][a5]!=-1)return f[a1][a2][a3][a4][a5];
     52     if(t>'Y') return f[a1][a2][a3][a4][a5]=1;
     53     f[a1][a2][a3][a4][a5]=0;
     54     if(a1+1<=5 && (ans[a1+1]==t || ans[a1+1]==0)) 
     55         f[a1][a2][a3][a4][a5]+=dfs(a1+1,a2,a3,a4,a5,t+1);
     56     if(a2+1<=a1 && (ans[a2+6]==t || ans[a2+6]==0)) 
     57         f[a1][a2][a3][a4][a5]+=dfs(a1,a2+1,a3,a4,a5,t+1);
     58     if(a3+1<=a2 && (ans[a3+11]==t || ans[a3+11]==0)) 
     59         f[a1][a2][a3][a4][a5]+=dfs(a1,a2,a3+1,a4,a5,t+1);
     60     if(a4+1<=a3 && (ans[a4+16]==t || ans[a4+16]==0)) 
     61         f[a1][a2][a3][a4][a5]+=dfs(a1,a2,a3,a4+1,a5,t+1);
     62     if(a5+1<=a4 && (ans[a5+21]==t || ans[a5+21]==0)) 
     63         f[a1][a2][a3][a4][a5]+=dfs(a1,a2,a3,a4,a5+1,t+1);
     64     return f[a1][a2][a3][a4][a5];
     65 }
     66 void solve() {
     67     scanf("%s",str+1);
     68     if(str[1]=='N') {
     69         scanf("%d",&d);
     70         ans[1]='A';
     71         siji(i,2,25) {
     72             siji(j,1,24) {
     73                 if(!used[j]) {
     74                     ans[i]='A'+j;
     75                     used[j]=1;
     76                     init();
     77                     int x=dfs(0,0,0,0,0,'A');
     78                     if(s+x>=d) break;
     79                     else {used[j]=0;s+=x;}
     80                 }
     81             }
     82         }
     83         printf("%s
    ",ans+1);
     84     }
     85     else {
     86         scanf("%s",str+1);
     87         ans[1]='A';
     88         //@used[1]=1这里多了一句这句话,实际上used是记录'A'+j被用过,如果这样我们就无法填B了
     89         siji(i,2,25) {
     90             xiaosiji(j,1,str[i]-'A'){
     91                 if(!used[j]) {
     92                     ans[i]='A'+j;
     93                     init();
     94                     s+=dfs(0,0,0,0,0,'A');
     95                 }
     96             }
     97             ans[i]=str[i];
     98             used[str[i]-'A']=1;
     99         }
    100         printf("%d
    ",s+1);
    101     }
    102 }
    103 int main(int argc, char const *argv[])
    104 {
    105 #ifdef ivorysi
    106     freopen("twofive.in","r",stdin);
    107     freopen("twofive.out","w",stdout);
    108 #else
    109     freopen("f1.in","r",stdin);
    110 #endif
    111     solve();
    112     return 0;
    113 }
  • 相关阅读:
    MVC3 中上传大文件
    js 将十进制转换为八位二进制数组
    nodejs 读取并处理二进制文件
    freeswitch源码编译 ./configure 遇到的问题
    通道设置静态坐席
    呼叫中心静态座席的配置
    ECharts报表
    combotree
    openlayer PanZoom
    为什么要始终使用PreparedStatement代替Statement?
  • 原文地址:https://www.cnblogs.com/ivorysi/p/6426103.html
Copyright © 2020-2023  润新知