• USACO4.3 Letter Game【枚举·细节】


    题意

    这道题的题目描述让我好一阵蒙,简述一下题意吧:

    给定一些字母的价值(如图所示),给出一个字符串(长度在$3$到$7$之间,可以出现重复的字母)和一个单词库。定义一个单词的价值就是它的字母的价值之和,一组单词的价值就是所有单词的价值之和,一组单词中的单词数量$>=1$,一组单词中的单词可以重复。要求用字符串中的字母拼成单词库中的一组单词,字符串中的字母不可以重复使用(如果字符串中有多个相同的字母,那么这个字母只能用出现的那么多次),求能够得到的单词组的最大价值并输出所有方案(按字典序)

    分析

    发现字符串的长度在$3$到$7$之间,单词的长度也在长度在$3$到$7$之间,说明一组单词最多有$2$个。

    给出的词库大小是$40000$,但是字符串的只在$3$到$7$之间,也就是最多只有$7$种字母,所以有大量的单词实际上是不合法的,我们可以在输入的时候把它们去掉,只保存有用的单词。

    更新一组里面只有一个单词的答案,然后两两枚举单词(一组),更新答案。

    利用题目给出的单词库本身按字典序排的性质,有序地遍历就可以保证顺序(良心题目)

      1 /*
      2 ID: Starry21
      3 LANG: C++
      4 TASK: lgame           
      5 */ 
      6 #include<cstdio>
      7 #include<algorithm>
      8 #include<vector>
      9 #include<cstring>
     10 #include<queue>
     11 using namespace std;
     12 #define ll long long
     13 #define INF 0x3f3f3f3f
     14 const int v[28]={2,5,4,4,1,6,5,5,1,7,6,3,5,2,3,5,7,2,1,2,4,6,6,7,5,7};
     15 char s[10];
     16 int cnt[30],c1[40005][30],c2[30];
     17 char dic[40005][10];
     18 int len[40005],val[40005];
     19 int n;
     20 int ans[40005][2];
     21 int num,maxx=0;
     22 void get(int i,int j)
     23 {
     24     int res=val[i]+val[j];
     25     if(res<maxx) return ;
     26     if(res>maxx)
     27     {
     28         maxx=res;
     29         num=0;//找到了更大的答案 重新来过 
     30         //ans[++num][0]=i,ans[num][1]=j;会在下面一个if里再算一次答案 
     31     } 
     32     if(res==maxx)
     33         ans[++num][0]=i,ans[num][1]=j;
     34     return ;
     35 }
     36 int main() 
     37 {
     38     //freopen("lgame.in","r",stdin);
     39     scanf("%s",s+1);
     40     for(int i=1;i<=strlen(s+1);i++)
     41         cnt[s[i]-'a']++;
     42     //freopen("lgame.dict","r",stdin);
     43     //freopen("lgame.out","w",stdout);
     44     while(scanf("%s",s+1)!=EOF)
     45     {
     46         if(s[1]=='.') break;
     47         n++;
     48         memcpy(c1[n],cnt,sizeof(cnt));
     49         int tmp=0;
     50         bool f=0;
     51         for(int i=1;i<=strlen(s+1);i++)
     52         {
     53             c1[n][s[i]-'a']--;
     54             if(c1[n][s[i]-'a']<0)
     55             {
     56                 f=1;
     57                 n--;
     58                 break;
     59             }
     60             tmp+=v[s[i]-'a'];
     61         }
     62         if(f) continue;
     63         strcpy(dic[n]+1,s+1);
     64         //puts(dic[n]+1);
     65         val[n]=tmp;
     66         len[n]=strlen(s+1);
     67         
     68     }//printf("%d
    ",n);
     69     for(int i=1;i<=n;i++)
     70     {
     71         //puts(dic[i]+1);
     72         get(i,0);
     73         for(int j=i+1;j<=n;j++)//字典序 1~i-1 get(j,i)不能保证第一个小 
     74         {
     75             bool f=0;
     76             memcpy(c2,c1[i],sizeof(c1[i]));
     77             for(int k=1;k<=len[j];k++)
     78             {
     79                 c2[dic[j][k]-'a']--;
     80                 if(c2[dic[j][k]-'a']<0)
     81                 {
     82                     f=1;
     83                     break;
     84                 }
     85             }
     86             if(f) continue;
     87             get(i,j);//字典序 
     88         }
     89     }
     90     printf("%d
    ",maxx);
     91     for(int i=1;i<=num;i++)
     92     {
     93         printf("%s",dic[ans[i][0]]+1);
     94         if(ans[i][1]) printf(" %s",dic[ans[i][1]]+1);
     95         puts("");
     96     }
     97     return 0;
     98 }
     99 /*
    100 prmgroa
    101 profile
    102 program
    103 prom
    104 rag
    105 ram
    106 rom
    107 .
    108 */
    Code
  • 相关阅读:
    Poly2Tri介绍[转]
    Threejs 开发3D地图实践总结【转】
    cesium and three.js【转】
    Three.js中如何显示帧速【转】
    Cesium学习笔记(七):Demo学习(自由控制飞行的飞机)[转]
    cesium原理篇(三)--地形(1)【转】
    cesium原理篇(二)--网格划分【转】
    Cesium原理篇:3D Tiles(1)渲染调度【转】
    shell脚本监控阿里云专线网络状态,若不通通过触发阿里云的进程监控报警
    jstat命令总结
  • 原文地址:https://www.cnblogs.com/lyttt/p/11808990.html
Copyright © 2020-2023  润新知