参考题解: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; }