当前位置:   article > 正文

USACO-Section 4.3 Letter Game (枚举)_usaco section 1.3dict

usaco section 1.3dict

描述

Lgame.gif

在家里用电视机做字母游戏是很流行的,其中一种玩法是:每一个字母有一个数值与之对应.你收集字母组成一个或多个词以得到尽可能高的得分.除非你已有了 “找词的方法”(“a way with words”),你会把你知道的字都试一遍.有时你也许会查阅其拼写,然后计算得分。显然可以用计算机更为准确地完成此任务。上图示出了英文字母及其所对应的值,当给出英文单词(word) 的表列及收集的字母时,请找出所能形成的得分最高的词或词对(pairs of words)。

[编辑]格式

PROGRAM NAME: lgame

INPUT FORMAT:

(file lgame.in)

输入文件lgame.in中有一行由小写字母(`a'到`z')组成的字符串, 这就是收集到字母(就是可以使用的字母),字符串由至少3个字母至多7个字母(以任意顺序) 组成。

(file lgame.dict)

词典文件lgame.dict由至多40,000行组成,文件的最后一行有'.' 表示文件的结束。其它各行每一行都是由至少3个小写字母,至多7 个小写字母组成的字符串。文件中的词已按字典顺序排序。

OUTPUT FORMAT:

(file lgame.out)

在文件lgame.out的第一行,你的程序应写上最高得分(子任务A).使用上面图形中给出的字母-值对应表。

随后的每一行是由文件lgame.dict中查到的具有这个得分的所有的词和或词对(word pairs)(子任务B)。要利用图中给定的字母的值。

当两个词能够形成 一个组合(具有给定的字母)时,这两个词应该打印到同一行,两个词中间用一个空格隔开。不许重复表示词对,例如'rag prom'和'prom rag'是同样的词对,只输出字典顺序较小的那个。

输出要按照字典顺序排序,如果两个词对第一个单词的顺序相同,则按照第二个单词。一个词对中的两个单词可以相同。

[编辑]SAMPLE INPUT(file lgame.in)

prmgroa

[编辑]SAMPLE INPUT(file lgame.dict)

profile
program
prom
rag
ram
rom
.

[编辑]SAMPLE OUTPUT

24
program
prom rag

很容易就能想到枚举,而且数据量很小,复杂度够了


主要是各种字符串匹配比较麻烦,幸亏有STL库,要不然估计很难写出来


  1. /*
  2. ID: your_id_here
  3. PROG: lgame
  4. LANG: C++
  5. */
  6. #include <cstdio>
  7. #include <cstring>
  8. #include <string>
  9. #include <vector>
  10. #include <map>
  11. #include <algorithm>
  12. #include <fstream>
  13. using namespace std;
  14. int sco[255],cnt[255]={0},tmp[255],maxv=0,len,ch[9];
  15. int num[9],all=0;
  16. bool vis[9];
  17. string ori;
  18. map<string,int> mp;
  19. map<string,bool> used;
  20. vector<string> ans;
  21. void dfs(string pre,string s,bool isSec) {
  22. if(s.size()>=3) {
  23. if(mp[s]!=0) {
  24. if(s.size()==3&&!isSec&&len>=6)//因为最多只有7个字符,所以若存在两个字符串,则有一个必定为3个字符
  25. dfs(s,"",true);
  26. if(isSec) {
  27. if(maxv<=mp[pre]+mp[s]) {
  28. if(maxv<mp[pre]+mp[s]) {//如果发现值更大的单词组
  29. maxv=mp[pre]+mp[s];
  30. ans.clear();
  31. used.clear();
  32. }
  33. if(pre<=s) {
  34. if(!used[pre+" "+s]) {//只放入为放入过的
  35. used[pre+" "+s]=true;
  36. ans.push_back(pre+" "+s);
  37. }
  38. }
  39. else {
  40. if(!used[s+" "+pre]) {
  41. used[s+" "+pre]=true;
  42. ans.push_back(s+" "+pre);
  43. }
  44. }
  45. }
  46. }
  47. else {
  48. if(maxv<=mp[s]) {
  49. if(maxv<mp[s]) {
  50. maxv=mp[s];
  51. ans.clear();
  52. used.clear();
  53. }
  54. if(!used[s]) {
  55. used[s]=true;
  56. ans.push_back(s);
  57. }
  58. }
  59. }
  60. }
  61. }
  62. for(int i=0;i<all;++i) {
  63. if(num[i]>0) {
  64. --num[i];
  65. string tmp=s;
  66. tmp.push_back(ch[i]);
  67. dfs(pre,tmp,isSec);
  68. ++num[i];
  69. }
  70. }
  71. }
  72. int main() {
  73. ifstream fin("lgame.in");
  74. ifstream dict("lgame.dict");
  75. ofstream fout("lgame.out");
  76. sco['q']=sco['j']=sco['z']=sco['x']=7;
  77. sco['w']=sco['f']=sco['k']=sco['v']=6;
  78. sco['y']=sco['p']=sco['g']=sco['h']=sco['b']=sco['m']=5;
  79. sco['u']=sco['d']=sco['c']=4;
  80. sco['o']=sco['l']=3;
  81. sco['r']=sco['t']=sco['a']=sco['n']=2;
  82. sco['e']=sco['i']=sco['s']=1;
  83. string s;
  84. fin>>ori;
  85. len=ori.size();
  86. for(int i=0;i<len;++i)//统计各单词出现
  87. ++cnt[ori[i]];
  88. for(int i='a';i<='z';++i)
  89. if(cnt[i]) {//将字符分组,可以避免同一个单词多次出现,相当于剪枝
  90. ch[all]=i;
  91. num[all++]=cnt[i];
  92. }
  93. while(dict>>s&&s[0]!='.') {
  94. memset(tmp,0,sizeof(tmp));
  95. for(int i=0;i<s.size();++i)
  96. ++tmp[s[i]];
  97. int tot=0;
  98. for(int i='a';i<='z';++i)
  99. if(tmp[i]>cnt[i]) {//若字典中的单词i字符个数 大于 ori中i字符个数,则该单词无效
  100. tot=-1;
  101. break;
  102. }
  103. else
  104. tot+=tmp[i]*sco[i];
  105. if(tot!=-1)//若ori串能形成当前串,则记录其分值
  106. mp[s]=tot;
  107. }
  108. dfs("","",false);
  109. fout<<maxv<<"\n";
  110. sort(ans.begin(),ans.end());//要按升序输出
  111. for(int i=0;i<ans.size();++i)
  112. fout<<ans[i]<<"\n";
  113. return 0;
  114. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/710475
推荐阅读
相关标签
  

闽ICP备14008679号