赞
踩
在家里用电视机做字母游戏是很流行的,其中一种玩法是:每一个字母有一个数值与之对应.你收集字母组成一个或多个词以得到尽可能高的得分.除非你已有了 “找词的方法”(“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'是同样的词对,只输出字典顺序较小的那个。
输出要按照字典顺序排序,如果两个词对第一个单词的顺序相同,则按照第二个单词。一个词对中的两个单词可以相同。
prmgroa
profile program prom rag ram rom .
24 program prom rag
很容易就能想到枚举,而且数据量很小,复杂度够了
主要是各种字符串匹配比较麻烦,幸亏有STL库,要不然估计很难写出来
- /*
- ID: your_id_here
- PROG: lgame
- LANG: C++
- */
- #include <cstdio>
- #include <cstring>
- #include <string>
- #include <vector>
- #include <map>
- #include <algorithm>
- #include <fstream>
-
- using namespace std;
-
- int sco[255],cnt[255]={0},tmp[255],maxv=0,len,ch[9];
- int num[9],all=0;
- bool vis[9];
- string ori;
- map<string,int> mp;
- map<string,bool> used;
- vector<string> ans;
-
- void dfs(string pre,string s,bool isSec) {
- if(s.size()>=3) {
- if(mp[s]!=0) {
- if(s.size()==3&&!isSec&&len>=6)//因为最多只有7个字符,所以若存在两个字符串,则有一个必定为3个字符
- dfs(s,"",true);
- if(isSec) {
- if(maxv<=mp[pre]+mp[s]) {
- if(maxv<mp[pre]+mp[s]) {//如果发现值更大的单词组
- maxv=mp[pre]+mp[s];
- ans.clear();
- used.clear();
- }
- if(pre<=s) {
- if(!used[pre+" "+s]) {//只放入为放入过的
- used[pre+" "+s]=true;
- ans.push_back(pre+" "+s);
- }
- }
- else {
- if(!used[s+" "+pre]) {
- used[s+" "+pre]=true;
- ans.push_back(s+" "+pre);
- }
- }
- }
- }
- else {
- if(maxv<=mp[s]) {
- if(maxv<mp[s]) {
- maxv=mp[s];
- ans.clear();
- used.clear();
- }
- if(!used[s]) {
- used[s]=true;
- ans.push_back(s);
- }
- }
- }
- }
- }
- for(int i=0;i<all;++i) {
- if(num[i]>0) {
- --num[i];
- string tmp=s;
- tmp.push_back(ch[i]);
- dfs(pre,tmp,isSec);
- ++num[i];
- }
- }
- }
-
- int main() {
- ifstream fin("lgame.in");
- ifstream dict("lgame.dict");
- ofstream fout("lgame.out");
-
- sco['q']=sco['j']=sco['z']=sco['x']=7;
- sco['w']=sco['f']=sco['k']=sco['v']=6;
- sco['y']=sco['p']=sco['g']=sco['h']=sco['b']=sco['m']=5;
- sco['u']=sco['d']=sco['c']=4;
- sco['o']=sco['l']=3;
- sco['r']=sco['t']=sco['a']=sco['n']=2;
- sco['e']=sco['i']=sco['s']=1;
-
- string s;
- fin>>ori;
- len=ori.size();
- for(int i=0;i<len;++i)//统计各单词出现
- ++cnt[ori[i]];
- for(int i='a';i<='z';++i)
- if(cnt[i]) {//将字符分组,可以避免同一个单词多次出现,相当于剪枝
- ch[all]=i;
- num[all++]=cnt[i];
- }
- while(dict>>s&&s[0]!='.') {
- memset(tmp,0,sizeof(tmp));
- for(int i=0;i<s.size();++i)
- ++tmp[s[i]];
- int tot=0;
- for(int i='a';i<='z';++i)
- if(tmp[i]>cnt[i]) {//若字典中的单词i字符个数 大于 ori中i字符个数,则该单词无效
- tot=-1;
- break;
- }
- else
- tot+=tmp[i]*sco[i];
- if(tot!=-1)//若ori串能形成当前串,则记录其分值
- mp[s]=tot;
- }
- dfs("","",false);
- fout<<maxv<<"\n";
- sort(ans.begin(),ans.end());//要按升序输出
- for(int i=0;i<ans.size();++i)
- fout<<ans[i]<<"\n";
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。