参考题解:http://www.cppblog.com/guyuecanhui/articles/88302.html
这两个题是差不多的,都是给出一些称量结果寻找“假”硬币(和其它硬币重量不同)。
用排除法,分情况讨论:
(1) 当结果为even(=)时,说明称上的几个硬币一定是真币
(2) 当结果为up(>)时,说明其余的硬币一定是真币,并且重的硬币一定在左边,轻的硬币一定在右边(所以这是把左边的硬币标记为重,右边的硬币标记为轻)。
(3) 当结果为down(<)时,说明其余的硬币一定是真币,并且重的硬币一定在右边,轻的硬币一定在左边(所以这是把左边的硬币标记为轻,右边的硬币标记为重)。
用一个数组记录每个钱币的状态,初始为-1(表示不确定状态),如果一定为真币记为0,如果可能较重记为2,如果可能较轻记为1,最后判断大于0的钱币一定为假币,而相应的状态表示它的相对重量。
如果上次判断一个钱币为真币,则不论下次结果如何,它还应当是真币;如果上次判断它可能较轻,而本次判断它可能较重,则它一定是真币(等于说是这种不平衡是由其它硬币造成的,因为如果该硬币为假币的话,假设它较重,那一定是它在哪边,哪边就较重,而不会出现这种又重又轻的情况),反之亦然!
//poj 1013
#include <cstdio>
#include <cstring>
#define N 12
int main()
{
int T, state[N], tmp[N], len;
char left[N], right[N], res[N];
scanf("%d", &T);
while(T--)
{
memset(state, -1, sizeof(state));
for(int i=1; i<=3; ++i)
{
scanf("%s %s %s", left, right, res);
len = strlen(left);
if(strcmp(res, "even") == 0)
{
for(int i=0; i<len; ++i)
state[left[i]-'A'] = 0, state[right[i]-'A'] = 0;
}
else if(strcmp(res, "down") == 0)
{
memcpy(tmp, state, sizeof(tmp));
memset(state, 0, sizeof(state));
for(int i=0; i<len; ++i)
state[left[i]-'A'] = 1, state[right[i]-'A'] = 2;
for(int i=0; i<12; ++i)
if(tmp[i] >= 0 && tmp[i] != state[i]) state[i] = 0;
}
else
{
memcpy(tmp, state, sizeof(tmp));
memset(state, 0, sizeof(state));
for(int i=0; i<len; ++i)
state[left[i] - 'A'] = 2, state[right[i]-'A'] = 1;
for(int i=0; i<12; ++i)
if(tmp[i] >= 0 && tmp[i] != state[i]) state[i] = 0;
}
}
for(int i=0; i<12; i++)
{
if(state[i] > 0)
{
printf("%c is the counterfeit coin and it is %s.\n", (char)(i+'A'), state[i] == 1 ? "light" : "heavy");
break;
}
}
}
return 0;
}
//poj 1029
#include <cstdio>
#include <cstring>
#define N 1005
int state[N], tmp[N], left[N/2], right[N/2];
int main()
{
int n, k, p, i, ans = 0;
char r[5];
scanf("%d %d", &n, &k);
memset(state, -1, sizeof(state));
while(k--)
{
scanf("%d", &p);
for(i=1; i<=p; ++i) scanf("%d", &left[i]);
for(i=1; i<=p; ++i) scanf("%d", &right[i]);
scanf("%s", r);
if(r[0] == '=')
{
for(i=1; i<=p; ++i)
state[left[i]] = 0, state[right[i]] = 0;
}
else if(r[0] == '<')
{
memcpy(tmp, state, sizeof(tmp));
memset(state, 0, sizeof(state));
for(i=1; i<=p; ++i)
state[left[i]] = 1, state[right[i]] = 2;
for(i=1; i<=n; i++)
if(tmp[i] >= 0 && tmp[i] != state[i]) state[i] = 0;
}
else
{
memcpy(tmp, state, sizeof(tmp));
memset(state, 0, sizeof(state));
for(i=1; i<=p; ++i)
state[left[i]] = 2, state[right[i]] = 1;
for(i=1; i<=n; i++)
if(tmp[i] >= 0 && tmp[i] != state[i]) state[i] = 0;
}
}
for(i=1; i<=n; ++i)
if(state[i])
ans++, p = i;
if(ans != 1) printf("0\n");
else printf("%d\n", p);
return 0;
}