poj-1029

7 篇文章 0 订阅
//396K	16MS	G++
#include <cstdio>
#include <cstring>

using namespace std;

const int MAX = 1005;

int coins[MAX]; 
char coinIsTrue[MAX];
char appear[MAX];

int leftPart[MAX];
int rightPart[MAX];

int coinNum;
int weightintTime;

int ABS(int a) {
	return a > 0 ? a: -a;
}

void solve(int * leftPart, int * rightPart, int weightCoinNum, char res) {
		switch (res) {
			case '=':
				for (int i = 1; i <= weightCoinNum; i++) {
					coins[leftPart[i]] = 0;
					coins[rightPart[i]] = 0;
					coinIsTrue[leftPart[i]] = 1;
					coinIsTrue[rightPart[i]] = 1;
				}
				break;
			case '<':
				for (int i = 1; i <= weightCoinNum; i++) {
					if (!coinIsTrue[leftPart[i]]) {
						coins[leftPart[i]]--;
					}
					if (!coinIsTrue[rightPart[i]]) {
						coins[rightPart[i]]++;
					}
				}
				break;
			case '>':
				for (int i = 1; i <= weightCoinNum; i++) {
					if (!coinIsTrue[leftPart[i]]) {
						coins[leftPart[i]]++;
					}
					if (!coinIsTrue[rightPart[i]]) {
						coins[rightPart[i]]--;
					}
				}
				break;
			default:
				break;
		}
}

int main() {
	scanf("%d %d", &coinNum, &weightintTime);
	for (int i = 1; i <= weightintTime; i++) {
		int weightCoinNum;
		scanf("%d", &weightCoinNum);
		for (int i = 1; i <= weightCoinNum; i++) {
			scanf("%d", &leftPart[i]);
			appear[leftPart[i]] = 1;
		}
		for (int i = 1; i <= weightCoinNum; i++) {
			scanf("%d", &rightPart[i]);
			appear[rightPart[i]] = 1;	
		}
		char res[10];
		scanf("%s", res);
		solve(leftPart, rightPart, weightCoinNum, res[0]);
	}
	int max = 0;
	int maxId = -1;
	char ifSameVal = 0;
	for (int i = 1; i <= coinNum; i++) {
		if (!coinIsTrue[i]) {
			// printf("%d\n", coins[i]);
			if (max <= ABS(coins[i])) {
				if (max == ABS(coins[i])) {
					ifSameVal = 1;
				} else {
					ifSameVal = 0;
				}
				max = ABS(coins[i]);
				maxId = i;
			}
		}
	}
	if (ifSameVal) {
		int firstUnAppearId = -1;
		int unAppearTime = 0;
		for (int i = 1; i <= coinNum; i++) {
			if (!appear[i]) {
				if (firstUnAppearId == -1) {
					firstUnAppearId = i;
				}
				unAppearTime++;
			}
		}
		if (unAppearTime == 1) { // if more than 1 coin are not weightted, still can not decided
			printf("%d\n", firstUnAppearId);
		} else {
			printf("0\n");
		}
	} else {
		if (max == 0) {
			printf("0\n");
		} else {
			printf("%d\n", maxId);
		}
	}
}


和1013基本思路一样,不过这次更复杂,首先假币最多只有一枚,也有可能没有的(输出0),因此要多加些条件判断,这次用了另外一种思路(其实本质一样):

http://blog.csdn.net/lyy289065406/article/details/6661421

首先time[]记录每个硬币的被怀疑程度,time[i]=0表示该硬币i不被怀疑(即其可能为真币)。定义在up状态盘的硬币为“轻怀疑假币”,通过“--”操作加深其被怀疑为轻假币的程度,“负号”为轻假币的怀疑方向;在down状态盘的硬币为“重怀疑假币”,通过“++”操作加深其被怀疑为重假币的程度,“正号”为重假币的怀疑方向。

那么若一枚真币被怀疑为“轻假币”时,它就可能通过下次称量通过“++”操作取消嫌疑了。初始化所有硬币的怀疑程度均为0。

称量完毕后,找出被怀疑程度最大(注意取绝对值)的硬币,它就是假币。而当其怀疑方向为正时,则其为重假币。为负时,为轻假币。


不过上面这个办法,在1013肯定有假币的情况下并且所有硬币都参加了称重是OK的,而本题其实不一定所有的硬币都称重了,并且可能没有假币,这就要求最后的判断要多加些处理.

最后处理完以后,判定:

首先看有没有最大怀疑度一样的多个coin,如果没有,那么就取最大的那个作为假币。

如果有最大怀疑度一样的coin,再判断,是否有没有参加称重的,如果没有参加称重的只有一个coin,那么该coin就是假币,如果多于一个coin没有称重, 那么无法确定,返回0. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值