毒酒幾何

2021-03-09 12:01:37

毒酒幾何
1000瓶酒中恐1瓶有毒,飲毒者10分鐘內必亡(與多少無關),現考慮用盡量少的小白鼠試毒。方案A:酒分兩大份,取一份讓鼠1均飲之,知一份中有毒,再分成兩大份,取一份讓鼠2均飲之,知一份中有毒,……如此,1000瓶酒,10只鼠足矣。然100分鐘太久,升級為方案B:酒分兩大份,取一份讓鼠1均飲之,兩份再分成四份,各取兩份讓鼠2均飲之,四份再分成八份,各取四份讓鼠3均飲之,……如此,1000瓶酒,10只鼠10+分鐘可行。最終形成易操作性執行方案C:鼠1隔一瓶飲一,鼠2隔兩瓶飲二,鼠3隔四瓶飲四瓶,鼠4隔八瓶飲八瓶,……(形似二進位制編碼中1表示喝,0表示不喝)。 程式設計根據給出的飲後死的老鼠的編號,計算出有毒的酒是哪一瓶(酒的編號為1,2,3……,老鼠的編號也是1,2,3,……)。

輸入格式:
一個字串:用逗號分隔的正整數序列(有效範圍內的死鼠編號)。無序,有可能有重複。若為空串表示無一鼠死亡(酒均無毒)。

輸出格式:
一個整數:毒酒的編號(第幾瓶酒有毒,若均無毒輸出0)。

輸入樣例:

3,7,9,1,5,3,2

輸出樣例:

343

解題思路:
直接採用位標記的方法解題。定義一個用於位標記的變數(看成是二進位制數),讀取字串中的每一個數,並將對應的數位標記為1,如此操作,最後該變數的十進位制的結果即為所求。

#include<stdio.h>
#include<string.h>
char str[1000];
int k=0;                       //用於位標記的變數
int main(){
    char* p;
    int num;
    gets(str);
    p=strtok(str,",");         //字串分割
    if(p==NULL){
        printf("%d",k);
        return 0;
    }
    else{
        sscanf(p,"%d",&num);       //型別轉換
        k=k|(1<<(num-1));          //設該位為1
        while(p=strtok(NULL,",")){
        sscanf(p,"%d",&num);
        k=k|(1<<(num-1));          //設該位為1
        }
        printf("%d",k);            //輸出結果
        return 0;
    }
}