精華區beta C_and_CPP 關於我們 聯絡資訊
作者 bleed1979 (十三) 看板 C_and_CPP 標題 [心得][ACM] 10315 - Poker Hands 時間 Fri Jun 11 00:28:35 2010 ─────────────────────────────────────── 撲克牌遊戲梭哈比較大小,我以往的作法是從同花順一路比到烏龍(什麼牌型都沒有)。 資料結構使用的是4 * 13的陣列。相信這也是較尋常的作法。 今次我用bit運算來實現梭哈遊戲的比較,希望能趨於高效。 題目︰http://icpcres.ecs.baylor.edu/onlinejudge/external/103/10315.html 中譯︰http://www.tcgs.tc.edu.tw/~sagit/luckycat/q10315.htm 題目的輸出為兩個玩家的手牌是黑方(前者)比較大還是白方(後者)比較大還是平手(Tie) 。 比較大小的定義請見中譯。 順子是沒有A2345,最大的順子是TJQKA。 除此之外,規則就和我們平常玩的一樣。 另外,此題允許相同的牌出現兩次以上。但不會有不合法的牌型(五張一樣)。 例如,4D 4D 7D 9D kD,視為同花,而不是一對(以最高者為之)。 比較大小是要比到底的。例如︰如果同樣是三條且三條的大小都一樣,要以廢牌決勝負。 題目定義好後,來決定資料結構。 因為只能使用條件判斷和位元運算,所以除了讀入資料是用char陣列以外,就不能再用陣 列。 以下是實做的資料結構︰ struct Poker { int type; int suit; int pair1, pair2; int rank; }; 和 一個bool值用以判斷是否形成三張一樣。 是的,您沒看錯,主要的資料結構只需要五個int。 type決定手牌的牌型(同花順,四條...等)。 suit代表花色。 rank代表牌的數字。 pair1和pair2代表如果有兩張以上一樣的牌的話,該一樣的牌的數字大小。 葫蘆和兩對都會需要用到pair2。 以下列出所有程式實作所用到的條件式,程式是邊讀入資料邊判斷的。 函式 - 讀牌 1.花色有兩種以上就不可能是同花或同花順。 2.數字大小有重複就不可能是順子和烏龍。 3.如果需要用到pair2就不可能是一對。 4.葫蘆和兩對的分別在於three這個bool值。 5.葫蘆和兩對是可以在讀到第五張牌就馬上可以判斷的,其餘牌型需要在做進一步判斷。 函式 - 確定牌型 6.如果不是葫蘆,就做進一步判斷。 7.如果可能是同花,只有同花和同花順這兩種可能。 8.如果可能是烏龍,只有順子和烏龍這兩種可能。 9.如果是兩對要把數字較大的對指定給pair1,較小的對存在pair2。 10.如果不是兩對也不是一對,只可能是四條或三條。四條只有兩個數字,三條有三個數 字。 函式 - 兩人手牌比較大小 11.兩人牌型不同,就可以判斷輸贏。否則就是牌型相同來比較數字。 12.葫蘆的第一對和第二對的大小都一樣。否則比pair1,相等再比pair2。 13.不是葫蘆,但可能是同花順,順子,同花或烏龍,比較數字大小。 14.如果是三條或四條,比較pair1,再比廢牌。 15.如果是一對,比較pair1,再比廢牌。 16.如果是兩對,比較pair1,再比pair2,再比廢牌。 以上條件判斷式看似都是廢話, 但要將其組合起來並避免冗餘,需要一定邏輯能力加上頭腦清晰。 以下就是實作的程式碼,僅供參考。 http://codepad.org/HQoUYFgf 至於速度上,原本的0.000s,現在的0.008s。 扣除UVa那裡精準度的調整,我只能說測資太少以至於無法分出勝負。 但我相信以位元運算應該可以比較快。 最後,我不想保證這個程式100%運作正確。 但可以通過UVa的所有測資,相信具有一定程度的正確性。 同時,由於對於位元運算來比較撲克牌大小是第一次經驗, 程式應該可以再精簡,有興趣的人請自行修改。 Bleed -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.43.117.3
ilovebbs:推~ 06/11 09:05