poj 1013 && poj 1029【寻找硬币】

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


你可能感兴趣的:(poj 1013 && poj 1029【寻找硬币】)