實現對編譯出來的名次進行順序排序

  前幾天,鵬哥在作業中給出了這樣一道題:

  5位運動員參加了10米臺跳水比賽,有人讓他們預測比賽結果

  A選手說:B第一,我第三。

  B選手說:我第二,E第四。

  C選手說:我第一,D第二。

  D選手說:C最後,我第三。

  E選手說:我第四,A第一。

  比賽結束後,每位選手都說對了一半,請編程確定比賽的名次。

這道題相信很多人都知道,程序寫起來也不是特別難,其主要的源程序如下:

#include<stdio.h>

int main()

{

int a , b , c , d , e;

int ret = 0;

for (a = 1; a < 6; a++)

{

    for (b = 1; b < 6; b++)

{

for (c = 1; c < 6; c++)

   {

   for (d = 1; d < 6; d++)

{

for (e = 1; e < 6; e++)

   {

   if ((b == 1) + (a == 3) == 1 &&

       (b == 2) + (e == 4) == 1 &&

       (c == 1) + (d == 2) == 1 &&

       (c == 5) + (d == 3) == 1 &&

       (e == 4) + (a == 1) == 1)

{

           printf("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e);

                                 }

     }

  }

    }

}

}

system("pause");

    return 0;

}

我自己當時也是寫到這裏的,本以爲就行了,可是輸出的結果並不是所期望的:


wKioL1Y2CQXxgY-yAAFzaWmCkNU646.jpg

如圖所示,這和我們所想的並不一樣,照理來說應該只有第一種一個答案纔對,而它將一些名次不連續的組也輸出來了,有人覺得那隻輸出第一行不就行了,可這只是一種取巧的方法,這道題只是它的答案恰好在第一行,那如果它在第二行或第三行以及其他行數呢?所以,這個程序還是要繼續改進的,這裏我和大家分享下學習到的方法:

  首先我們目的是想讓其按連續的順序輸出來,中間不要空出數字,那我們可以將它放入一個二進制位中,如果它存入的值是連續的1,那就說明這個次序是連續的。

      比如給定義一個 int ret=0,由於只有5個名次,所以這裏ret只看它後八位,剛開始ret應該是0000 0000,如果是1的話,可直接讓它和ret相或,其結果是1,如果是2的話就讓1左移一位再和ret相或,如果是3就把1左移兩位再相或,以此類推,如果是n的話,就讓1左移(n-1)位和ret相或,這樣就能確保它的名次是連續的了,具體的代碼如下:

ret = ret | 1 << (a - 1);

ret = ret | 1 << (b - 1);

ret = ret | 1 << (c - 1);

ret = ret | 1 << (d - 1);

ret = ret | 1 << (e - 1);

這是我們將所有的名次存入ret中

下一步我們就該判斷ret的二進制是否爲連續的1,那我們可以用while循環和if語句來實現,代碼如下:


while (ret)

{

if (ret % 2 == 0)

break;

else ret = ret / 2;

}

如果while循環整個執行完畢,那說明我們的ret此時爲0,並且名次是按連續的順序輸出的;如果從break跳出循環的話,那此時ret就不等於0,也說明名次並不是按順序輸出的。因此整個程序的代碼應該是這樣的:

#include<stdio.h>

int main()

{

int a , b , c , d , e;

int ret = 0;

for (a = 1; a < 6; a++)

{

for (b = 1; b < 6; b++)

{

for (c = 1; c < 6; c++)

{

for (d = 1; d < 6; d++)

{

for (e = 1; e < 6; e++)

{

if ((b == 1) + (a == 3) == 1 &&

(b == 2) + (e == 4) == 1 &&

(c == 1) + (d == 2) == 1 &&

(c == 5) + (d == 3) == 1 &&

(e == 4) + (a == 1) == 1)

{

ret = 0;

ret = ret | 1 << (a - 1);

ret = ret | 1 << (b - 1);

ret = ret | 1 << (c - 1);

ret = ret | 1 << (d - 1);

ret = ret | 1 << (e - 1);

while (ret)

{

if (ret % 2 == 0)

break;

else ret = ret / 2;

}

if (ret == 0)

    printf("a=%d,b=%d,c=%d,d=%d,e=%d\n", a, b, c, d, e);

  

}

}

}

}

}

}

system("pause");

    return 0;

}

其運行結果如下:

wKiom1Y2HUWQNokrAACYOFyj2Vc505.jpg

在這裏要注意下每次給每個名次組存放的時候,要把ret初始化,這樣就不會將上次的值再傳遞到這次。

整個過程和流程就是這樣,當然我這也不是最簡單,最好的方法,肯定還有大神有其他好的方法,如果有的話,可以在留言中分享,謝謝j_0057.gif


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章