POJ 1029--False coin

題意

題目意思是講,有若干個硬幣,其中可能存在一個質量有誤的。現在通過許多次比較來確定哪個的質量不同於其他硬幣。

分析

每一次比較的時候,只要不是“=”,顯然兩邊的任何一個硬幣都有嫌疑。因此,在每一次不是“=”的時候,爲所有嫌疑幣施加一個嫌疑值。我們約定讓天平較低一方的所有硬幣,嫌疑值-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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章