Uva489
题意:
给定两个字符串,第一个串是用来匹配的,从第二个串的第一个字符开始匹配,如果第二个串中的字符在第一个串出现,则表示猜中了,第一个串中的相同的那个字符都算被猜中;如果没有出现则表示猜错,同样的猜错只算一次。在整个匹配的过程中,如果在还没猜错7次之前,第一个串中所有的字符都被猜完了, 则输出“You win.”,如果你还没全部猜完的时候就已经猜错7次,则输出“You lose.”。如果整个匹配过程结束后,你没赢也没输,则输出“You chickened out.”。
题意翻译转载于:http://blog.csdn.net/acb0y/article/details/6838682
解法:定义cnt1[26],cnt2[26]用于记录串S1,S2中字母是否出现出现过将cnt[i]设为1.再将cnt1,cnt2进行比对。
(26的数组太长不好表示,下面以10为例)
Eg_1:
s1:bdi
s2:bfghij
cnt1:
0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
cnt2
0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
1.5个(cnt1,cnt2取值不同的地方)
2.同为1的地方有两个,也就是说s1比对完了且只有两个相同,可是没有达到最大错误次数。则输出“You chickened out.”。
s2:bdffiacc
cnt1:
0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
输出:“YOU WIN”。
总结:使用桶的思路,用数组记录字母出现次数,再将两个数组对比得出结论。时间复杂度为O(N).
以下是代码:
#include <iostream>
#define max 100
#include<cstring>
using namespace std;
int main()
{
int cnt1[26],cnt2[26];
int n;
memset(cnt1,0,sizeof(cnt1));
memset(cnt2,0,sizeof(cnt2));
char s1[max],s2[max];
while(cin>>n&&n!=-1&&cin>>s1&&cin>>s2)
{
int cs1=0,cs2=0,effor_count=0,ture_count=0;//分别用于读取cnt1,cnt2对应位置的元素,effor_count为不同位置计数器
int s1_count=0;//s1_count为s1中不重复字母个数
cout<<"Round"<<n<<endl;
for(int i=0;i<strlen(s1);i++)//将字母出现过的地方标记为1
{
cnt1[int(s1[i]-96)] = 1;//int(s1[i]-96),a的ASKII码是97,该句意思是将字符转化为整数顺序
}
for(int j=0;j<strlen(s2);j++)
{
cnt2[int(s2[j]-96)] = 1;//int(s2[j]-96),a的ASKII码是97,该句意思是将字符转化为整数顺序
}
for(int k=0;k<26;k++)
{
if(cnt1[cs1]==1) s1_count++;
if(cnt1[cs1]!=cnt2[cs2]){
effor_count++;
if(effor_count>7){
cout<<"You lose"<<endl;
break;}
}
if(cnt1[cs1]==cnt2[cs2]&&cnt1[cs1]==1) ture_count++;
cs1++;
cs2++;
}
if(effor_count<=7&&ture_count==s1_count) cout<<"You win"<<endl;
if(effor_count<=7&&ture_count!=s1_count) cout<<"You chickened out"<<endl;
}
return 0;
}