題意
題目意思是講,有若干個硬幣,其中可能存在一個質量有誤的。現在通過許多次比較來確定哪個的質量不同於其他硬幣。
分析
每一次比較的時候,只要不是“=”,顯然兩邊的任何一個硬幣都有嫌疑。因此,在每一次不是“=”的時候,爲所有嫌疑幣施加一個嫌疑值。我們約定讓天平較低一方的所有硬幣,嫌疑值-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;
}