![](http://acm.nankai.edu.cn/images/puz.gif)
Time Limit: 1000 ms Memory Limit: 65536 kB
Total Submit : 74 (18 users) Accepted Submit : 15 (13 users) Page View : 318
近些年语音识别技术越来越流行,要检验语音识别技术是否精准,可采用如下方法:第一台机器发声读单词,第二台根据第一台发出的声音进行语音识别并发声,第三台接收第二台发出的声音并发声……以此类推,直到最后一台机器发声。
由于这个过程中可能会出现一些偏差,机器很多时,最后听到的话往往会和初始句子有很大出入。经过几轮实验后,我们注意到在两台机器间传达时,有些单词往往会错误地变成其他特定的单词,而有些单词不会改变。我们已经收集到了这样的一个单词转化的列表,现在想要知道初始句子到最后会变成什么样子,请写程序来实现。
由于这个过程中可能会出现一些偏差,机器很多时,最后听到的话往往会和初始句子有很大出入。经过几轮实验后,我们注意到在两台机器间传达时,有些单词往往会错误地变成其他特定的单词,而有些单词不会改变。我们已经收集到了这样的一个单词转化的列表,现在想要知道初始句子到最后会变成什么样子,请写程序来实现。
Input
输入包括多组数据。
第一行是整数T (1<=T<=100),表示有多少组测试数据。
每组数据第一行包括两个整数N和M (2<=N<=100, 0<=M<=100),分别表示机器的数量和单词转化列表长度。随后有M行,每行包含两个用空格隔开的单词a和b,表示单词a在传话中一定会变成b。输入数据保证没有重复。最后一行包含若干个用单个空格隔开的单词,表示初始句子,句子总长不超过100个字符。同一个单词的不同时态被认为是不同的单词。
当然,如前所述,不在列表中的单词永远不会变化。
第一行是整数T (1<=T<=100),表示有多少组测试数据。
每组数据第一行包括两个整数N和M (2<=N<=100, 0<=M<=100),分别表示机器的数量和单词转化列表长度。随后有M行,每行包含两个用空格隔开的单词a和b,表示单词a在传话中一定会变成b。输入数据保证没有重复。最后一行包含若干个用单个空格隔开的单词,表示初始句子,句子总长不超过100个字符。同一个单词的不同时态被认为是不同的单词。
当然,如前所述,不在列表中的单词永远不会变化。
Output
对于每组测试数据,单独输出一行“Case #c: s” (不含引号)。 其中,c为测试数据编号,s为最后我们所听到的句子。s的格式与输入数据中初始句子格式相同。
Sample Input
2 4 3 ship sheep sinking thinking thinking sinking the ship is sinking 10 5 tidy tiny tiger liar tired tire tire bear liar bear a tidy tiger is tired
Sample Output
Case #1: the sheep is thinking Case #2: a tiny bear is bear
Source
Best User : cztianshi
我首先用的字典树,但过不了,后来看了大神的模仿可以说完全照抄的吧,改用STL最终解决了,但我弄不明白为什么字典树就错了,可能有其他非大小写字符吧!
/*
我的程序
#include<iostream>
using namespace std;
struct Trie
{
Trie * next[26];
char new_word[100];
bool flag;//标记是否是单词的结尾
}*root;/可以不用存真的数据元素
void insert(char *str1,char *str2)
{
int len =strlen(str1);
Trie *s = root;
for (int i = 0; i < len; i++)
{
if (s->next[str1[i] - 'a'])
s = s->next[str1[i] - 'a'];
else
{
Trie* t = new Trie;
memset(t, 0, sizeof (Trie));
s->next[str1[i] - 'a'] = t;
s = t;
}
}
strcpy(s->new_word,str2);
//cout<<s->new_word<<" "<<endl;
s->flag = 1;
}
int find(char *str)
{
int len = strlen(str);
// cout<<str<<" "<<len<<endl;
Trie *s = root;
for (int i = 0; i < len; i++)
{
if (s->next[str[i] - 'a'])
s = s->next[str[i] - 'a'];
else
return 0;
}
if(s->flag==1)
strcpy(str,s->new_word);
return s->flag;/flag可能不标志为单词结尾
}
void del(Trie *root)
{
Trie *s = root;
for (int i = 0; i < 26; i++)
{
if (s->next[i])
del(s->next[i]);
}
delete s;
s = NULL;
}
int main()
{
int t,n,m,i,start,j,k,tag=0;
char str1[100],str2[100],alticle[100],word[100],new_alticle[100][100];
cin>>t;
while(t--)
{
tag++;
root=new Trie;
memset(root,0,sizeof(Trie));
cin>>n>>m;
for(i=0;i<m;i++)
{
cin>>str1>>str2;
insert(str1,str2);
}
getchar();
// cout<<"&&&&&"<<endl;
gets(alticle);
puts(alticle);
// cout<<"&&&&&"<<endl;
start=0;
k=0;
for(i=0;alticle[i]!=0;i++)
{
if(alticle[i]==' ')
{
word[start]=0;
// cout<<word<<" ";
for(j=0;j<n-1;j++)
{
find(word);
}
strcpy(new_alticle[k++],word);
// cout<<word<<" ";
start=0;
}
if(alticle[i]!=' ')word[start++]=alticle[i];
}
word[start]=0;
// cout<<word<<" ";
for(j=0;j<n-1;j++)
{
find(word);
}
strcpy(new_alticle[k++],word);
cout<<"Case #"<<tag<<": ";
for(i=0;i<k-1;i++)
cout<<new_alticle[i]<<" ";
cout<<new_alticle[i]<<endl;
del(root);
}
return 0;
}
*/
///大神的程序
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
using namespace std;
map<string,string>::iterator iter;
int main()
{
string a,b,word;
int t,n,m,i,j,tag=0;
char alticle[1200];
cin>>t;
while(t--)
{
tag++;
map<string,string>temp;
cin>>n>>m;
for(i=0;i<m;i++)
{
cin>>a>>b;
temp[a]=b;
}
getchar();
gets(alticle);
printf("Case #%d:",tag);
word="";
for(i=0;alticle[i]!=0;i++)
{
if(alticle[i]!=' ')
word+=alticle[i];
else
{
for(j=0;j<n-1;j++)
{
if((iter=temp.find(word)) !=temp.end())
word=iter->second;
}
cout<<" "<<word;
// printf(" %s",word.c_str());
word="";
}
}
for(j=0;j<n-1;j++)
{
if((iter=temp.find(word))!=temp.end())
word=iter->second;
}
// printf(" %s\n",word.c_str());
cout<<" "<<word<<endl;
}
return 0;
}