题意
题目意思是讲,有若干个硬币,其中可能存在一个质量有误的。现在通过许多次比较来确定哪个的质量不同于其他硬币。
分析
每一次比较的时候,只要不是“=”,显然两边的任何一个硬币都有嫌疑。因此,在每一次不是“=”的时候,为所有嫌疑币施加一个嫌疑值。我们约定让天平较低一方的所有硬币,嫌疑值-1,让较高的+1。当出现“=”的时候,重置两侧硬币的嫌疑值为0(这些硬币质量肯定正确)。假定最后只有一个硬币的嫌疑值不为0,那么显然这个币质量不同于其他,如果有多个非0,那么便是绝对值较大的。
至于理由,其实也简单。假定有异常硬币重于其他的硬币,那么它的嫌疑值便会一直增加。而其他硬币跟这枚异常币在一个托盘的时候,嫌疑值会增加,但在对面托盘的时候,嫌疑值会降低,那么最后它们的嫌疑值的绝对值便小于异常币。最后如果出现多个最大绝对值,说明有一枚币跟异常币一直在一个托盘,或者一直在对面托盘,这样显然在题目要求下无解。异常币要么不存在,要么只会有一个,所以此法可行。
代码如下:
Memory: 124K Time: 16MS Length: 79LINES
#include<cstdlib>
#include<cstdio>
int ArrInt[1001] = {};
bool ArrBl[1001] = {};
int num[1000] = {};
int N = 0;
int K = 0;
int Pi = 0;
char cmp;
int sign = 0;
int main()
{
scanf("%d%d", &N, &K);
for (int i = 0; i < K; ++i)
{
scanf("%d", &Pi);
for (int j = 0; j < Pi * 2; ++j) scanf("%d", &num[j]);
getchar();
scanf("%c", &cmp);
if (cmp == '=')
for (int k = 0; k < Pi; ++k)
ArrBl[num[k]] = ArrBl[num[k + Pi]] = true;
else if (cmp == '<')
{
++sign;
for (int k = 0; k < Pi; ++k)
{
if (!ArrBl[num[k]]) --ArrInt[num[k]];
if (!ArrBl[num[k + Pi]]) ++ArrInt[num[k + Pi]];
}
}
else
{
++sign;
for (int k = 0; k < Pi; ++k)
{
if (!ArrBl[num[k]]) ++ArrInt[num[k]];
if (!ArrBl[num[k + Pi]]) --ArrInt[num[k + Pi]];
}
}
}
int key = 0;
int key2 = 0;
int count = 0;
int first = 0;
int seconed = 0;
for (int i = 1; i <= N; ++i)
{
if (sign == 0)
{
if (!ArrBl[i])
{
if (++count > 1) break;
key = i;
}
}
else
{
if (!ArrBl[i] && ArrInt[i] != 0)
{
if (abs(ArrInt[i]) >= seconed)
{
first = seconed;
seconed = abs(ArrInt[i]);
key2 = i;
}
++count;
key = i;
}
}
}
if (count == 1) printf("%d\n", key);
else
{
if (sign == 0 || first == seconed) printf("%d\n", 0);
else printf("%d\n", key2);
}
return 0;
}