//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.