思路是:如果是even,那么左右出现的都不是要找的那个,排除出去。对所有的重的一边取个交集,对所有轻的一边也取个交集。交集排除掉even的应该是空的或者只有一个。这个就是要找的。原因是 如果一个coin是重的,那么它必须出现在所有不even的重的一侧,因而是重的一侧的交集。如果coin是轻的,与此同理。
input.txt
12
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
AGHL BDEC even
JKI ADE up
J K even
ABCDEF GHIJKL up
ABC DEF even
I J down
ABCDEF GHIJKL up
ABHLEF GDIJKC down
CD HA even
A B up
B A down
A C even
A B up
B C even
DEFG HIJL even
ABC DEJ down
ACH IEF down
AHK IDJ down
ABCD EFGH even
AB IJ even
A L down
EFA BGH down
EFC GHD even
BA EF down
A B up
A C up
L K even
ACEGIK BDFHJL up
ACEGIL BDFHJK down
ACEGLK BDFHJI down
ACEGIK BDFHJL up
ACEGIL BDFHJK down
ACEGLK BDFHJI up
output.txt
K is the counterfeit coin and it is light.
I is the counterfeit coin and it is heavy.
I is the counterfeit coin and it is light.
L is the counterfeit coin and it is light.
B is the counterfeit coin and it is light.
A is the counterfeit coin and it is heavy.
A is the counterfeit coin and it is light.
L is the counterfeit coin and it is heavy.
A is the counterfeit coin and it is light.
A is the counterfeit coin and it is heavy.
L is the counterfeit coin and it is light.
K is the counterfeit coin and it is heavy.
1013 | Accepted | 700K | 0MS | G++ | 2769B |
/*
ID: thestor1
LANG: C++
TASK: poj1013
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>
using namespace std;
int main()
{
std::ios::sync_with_stdio(false);
std::vector<bool> ups(12);
std::vector<bool> downs(12);
std::vector<bool> tmps(12);
int n;
cin >> n;
string lhs, rhs, result;
for (int t = 0; t < n; ++t)
{
fill(ups.begin(), ups.end(), true);
fill(downs.begin(), downs.end(), true);
for (int k = 0; k < 3; ++k)
{
cin >> lhs >> rhs >> result;
if (result == "even")
{
for (int i = 0; i < lhs.size(); ++i)
{
ups[lhs[i] - 'A'] = false;
downs[lhs[i] - 'A'] = false;
}
for (int i = 0; i < rhs.size(); ++i)
{
ups[rhs[i] - 'A'] = false;
downs[rhs[i] - 'A'] = false;
}
}
else if (result == "up")
{
fill(tmps.begin(), tmps.end(), false);
for (int i = 0; i < lhs.size(); ++i)
{
tmps[lhs[i] - 'A'] = true;
}
for (int i = 0; i < ups.size(); ++i)
{
if (!(ups[i] && tmps[i]))
{
ups[i] = false;
}
}
fill(tmps.begin(), tmps.end(), false);
for (int i = 0; i < rhs.size(); ++i)
{
tmps[rhs[i] - 'A'] = true;
}
for (int i = 0; i < downs.size(); ++i)
{
if (!(downs[i] && tmps[i]))
{
downs[i] = false;
}
}
}
else
{
assert (result == "down");
fill(tmps.begin(), tmps.end(), false);
for (int i = 0; i < lhs.size(); ++i)
{
tmps[lhs[i] - 'A'] = true;
}
for (int i = 0; i < downs.size(); ++i)
{
if (!(downs[i] && tmps[i]))
{
downs[i] = false;
}
}
fill(tmps.begin(), tmps.end(), false);
for (int i = 0; i < rhs.size(); ++i)
{
tmps[rhs[i] - 'A'] = true;
}
for (int i = 0; i < ups.size(); ++i)
{
if (!(ups[i] && tmps[i]))
{
ups[i] = false;
}
}
}
}
bool found = false;
for (int i = 0; i < ups.size(); ++i)
{
if (ups[i])
{
cout << (char)('A' + i) << " is the counterfeit coin and it is heavy." << endl;
found = true;
break;
}
}
if (found)
{
continue;
}
for (int i = 0; i < downs.size(); ++i)
{
if (downs[i])
{
cout << (char)('A' + i) << " is the counterfeit coin and it is light." << endl;
found = true;
break;
}
}
assert (found);
}
return 0;
}