poj 1013 Counterfeit Dollar
#include <iostream>
#include <map>
#include <string>
using namespace std;
string str1[3],str2[3],com[3];
/*
若没有is_counterfeit()函数,则下面测试数据的输出结果是 G,但正确应该是 I
ABCDEF GHIJKL up
ABC DEF even
I J down
*/
bool is_counterfeit(char a)
{
for(int i=0;i<3;i++)
{
if(com[i]=="even")
continue;
if(str1[i].find(a)==string::npos&&str2[i].find(a)==string::npos)
return false;
}
return true;
}
int main()
{
int n,i,t;
scanf("%d",&n);
while(n--)
{
map<char ,int > weight;
map<char ,int>::iterator ite;
for(t=0;t<3;t++)
{
cin>>str1[t]>>str2[t]>>com[t];
if(com[t]=="even")
{
for(i=0;i<str1[t].size();i++)
weight[str1[t][i]]=0;
for(i=0;i<str2[t].size();i++)
weight[str2[t][i]]=0;
}
else
{
int tag=-1;
if(com[t]=="up")
tag*=-1;
for(i=0;i<str1[t].size();i++)
{
ite=weight.find(str1[t][i]);
if(ite==weight.end())
weight[str1[t][i]]=tag;
else if(ite!=weight.end()&&ite->second!=tag)
weight[str1[t][i]]=0;
}
for(i=0;i<str2[t].size();i++)
{
ite=weight.find(str2[t][i]);
if(ite==weight.end())
weight[str2[t][i]]=-tag;
else if(ite!=weight.end()&&ite->second!=-tag)
weight[str2[t][i]]=0;
}
}
}
ite=weight.begin();
while(ite!=weight.end())
{
if(ite->second<0&&is_counterfeit(ite->first))
printf("%c is the counterfeit coin and it is light. \n",ite->first);
else if(ite->second>0&&is_counterfeit(ite->first))
printf("%c is the counterfeit coin and it is heavy. \n",ite->first);
else
{
ite++;
continue;
}
break;
}
}
return 0;
}
//思路:若是even,则两串都不是Counterfeit Dollar,都标记为0,若是up,则第一串中有个重的或第二串中有个轻的
//则把第一串每个字符标记为1,表示有可能为重的,第二串标记为-1;
//若一个字符出现两次以上,若第一次标记为0,则一直是0,之后的任何一次不管标记是-1,0,1,都不用再作修改了
//若第一次标记为1,之后的任何一次如果出现0或者-1,则固定成0,如果一直是1,则不作修改