USACO 4.3.4 Letter Game 字母游戏 题解与分析

Letter Game字母游戏

IOI 1995

译 by kd

描述

USACO 4.3.4 Letter Game 字母游戏 题解与分析_第1张图片
在家里用电视机做字母游戏是很流行的,其中一种玩法是:每一个字母有一个数值与之对应.你收集字母组成一个或多个词以得到尽可能高的得分.除非你已有了 “找词的方法”(“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(filelgame.dict)

profile
program
prom
rag
ram
rom
.

SAMPLE OUTPUT

24
program
prom rag
【分析】:
    字符串处理题。                                                           
    首先,对lgame.dict文件进行处理,每读入一行就处理一次对应的键盘值<用map建立一一对应关系,即一个单词对应一个键盘值和>                                   
    然后,读入单词,为满足输出字典序,先对原单词每一个字母排序<字典序>,对于该单词每一个字符串的排列<这里实现“排列”用STL中的next_permutation(word.begin(),word.end()>,进行如下处理:
    首先,题目中提到"find the highest scoring words or pairs of words that can be formed." 就是说,让你找到最高的得分,在第一行输出然后下面要输出所有的得分最高的单词或词组,并且按照字典序输出.额,给出的单词长度在3~7之间,所以最多只能用两个单词。
    然后枚举1≤i≤len,i≤j≤len,每次分别取这一个排列中的词分别为:从0-i位<记Q>和i-(j-i)位<记W>。为了满足“不许重复表示词对,例如'rag prom'和'prom rag'是同样的词对,只输出字典顺序较小的那个”,由于对于同一字母组合来说必存在第一个单词字典序小于第二个,因此如果Q的字典序大于W,直接弹出,避免如“parr mog”和“mog parr”同时出现,或字典中不存在Q或W的情况,都直接继续枚举,不增加答案,然后更新答案即可
 
【测评信息】:
      TASK: lgame
      LANG: C++
      Compiling...
      Compile: OK
      Executing... 
      Test 1: TEST OK [0.140 secs, 5900 KB] 
      Test 2: TEST OK [0.097 secs, 5636 KB] 
      Test 3: TEST OK [0.097 secs, 5636 KB] 
      Test 4: TEST OK [0.140 secs, 5900 KB] 
      Test 5: TEST OK [0.097 secs, 5636 KB] 
      Test 6: TEST OK [0.140 secs, 5900 KB] 
      Test 7: TEST OK [0.119 secs, 5768 KB] 
      Test 8: TEST OK [0.086 secs, 5636 KB] 
      Test 9: TEST OK [0.097 secs, 5636 KB] 
      Test 10: TEST OK [0.140 secs, 5900 KB] 
      Test 11: TEST OK [0.130 secs, 5768 KB] 
      Test 12: TEST OK [0.184 secs, 6296 KB]
      All tests OK.
 
【代码】:
/*
   ID:csyzcyj1
   PROG:lgame
   LANG:C++
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<map>
using namespace std;
#define MAXWORD 27
map<string,int> vword;
map<string,bool> exist;
vector<string> ans;
int value[MAXWORD],ans1=0;
string word;
void pre_dict()
{
      string use;
      value['q'-'a']=7;
	  value['w'-'a']=6;
	  value['e'-'a']=1;
	  value['r'-'a']=2;
	  value['t'-'a']=2;
	  value['y'-'a']=5;
	  value['u'-'a']=4;
	  value['i'-'a']=1;
	  value['o'-'a']=3;
	  value['p'-'a']=5;
	  value['a'-'a']=2;
	  value['s'-'a']=1;
	  value['d'-'a']=4;
	  value['f'-'a']=6;
	  value['g'-'a']=5;
	  value['h'-'a']=5;
	  value['j'-'a']=7;
	  value['k'-'a']=6;
	  value['l'-'a']=3;
	  value['z'-'a']=7;
	  value['x'-'a']=7;
	  value['c'-'a']=4;
	  value['v'-'a']=6;
	  value['b'-'a']=5;
	  value['n'-'a']=2;
	  value['m'-'a']=5;
	  //ios::sync_with_stdio(false);
	  vword[""]=0;
	  while(cin>>use && use!=".")
	  {
            int all=0;
            for(int i=0;i<(int)use.size();i++)
                  all+=value[use[i]-'a'];
            vword[use]=all;
      }
}
void work()
{      
      sort(word.begin(),word.end());
      do
      {
            for(int i=1;i<=(int)word.size();i++)
                  for(int j=i;j<=(int)word.size();j++)
                  {
                        string use1,use2,useword;
                        use1=word.substr(0,i);
                        use2=word.substr(i,j-i);
                        if(i!=j && use1>use2)   continue;
                        if(!vword[use1] || (!vword[use2] && i!=j))   continue;
                        
                        useword=use1;
                        if(i!=j)   useword+=" ",useword+=use2;

                        if(ans1==vword[use1]+vword[use2] && !exist[useword])
                        {
                              exist[useword]=true;
                              ans.push_back(useword);
                        }
                        else if(ans1<vword[use1]+vword[use2])
                        {
                              ans1=vword[use1]+vword[use2];
                              exist.clear();
                              ans.clear();
                              exist[useword]=true;
                              ans.push_back(useword);                              
                        }
                  }  
      }while(next_permutation(word.begin(),word.end()));//产生排列 
}
int main()
{
	  freopen("lgame.dict","r",stdin);
	  pre_dict();//对dict文件处理 
	  
      freopen("lgame.in","r",stdin);
      freopen("lgame.out","w",stdout);
      //ios::sync_with_stdio(false); 	
      cin>>word;
      
      work();
      
      printf("%d\n",ans1);
      for(int i=0;i<(int)ans.size();i++)
            cout<<ans[i]<<endl;
	  //system("pause");
      return 0;
}

转载注明出处:http://blog.csdn.net/u011400953

你可能感兴趣的:(USACO 4.3.4 Letter Game 字母游戏 题解与分析)