模擬賽 模擬題
1.送分題(ptgiving.cpp/c/pas)
【問題背景】
眾所周知, xkj是GH的得意門生,可是 xkj的數學成績並不是很理想,每次GH在批評完數學限訓做的差的人後,總會在後面加上一句,咱們班還有一位做的最差的同學——xkj,你看看你還有對號嗎,居然比cdy做得還差!
xkj當然是不服的啦,當場跟GH van♂硬幣。在玩完硬幣後,生成了一系列隨機的亂七八糟的數字,並把他們整列成科學計數法的形式,並排序成有序的序列,還計算出排序的最小成本之後,終於,從桌堂裡掏出了一本古老的小黃書——來自c。的透徹祕籍。這是xkj、c。和cdy在學gxt和lsq做生意時偷偷找到的祕籍,被c。私吞了,今天xkj冒著風險偷了過來,並偷偷地傳給了cdy,就去跳瑰麗華爾茲去了。
【問題描述】
cdy自從拿到了小黃書之後就興奮地不得了,三天後終於有時間在站級部且mt不在的時候和xiaoY一起透徹這本小黃書。(然而此時xkj的靈魂已經飄到了食堂)
開啟一看,這本小黃書裡竟然有一個奇怪的遊戲。由於這本書是c。珍藏的,太古老了已經破爛不堪了,所以cdy只知道這個遊戲是用黑桃、紅心、梅花和方片,A到K的52張牌(不包含大貓和小貓)的進行撲克牌遊戲。
由於這本書已經破爛不堪,中間描述遊戲規則的部分已經被扯成ghj1222的頭像那樣了,cdy只看到了“每個人的手牌上限有5張”這個資訊,所以cdy和xy決定每個人發五張牌,並判定誰的手牌比較大。這本小黃書中規定手牌大小判定的資訊如下:
所有五張牌的組合,按以下順序,由大到小排行分為不同牌型:
編號 | 名稱 | 英文名稱 | 描述 | 舉例 |
---|---|---|---|---|
1 | 同花順 | Straight Flush | 同一花色順序的牌。 | Q♦ J♦ 10♦ 9♦ 8♦ |
2 | 四條 | Four of a Kind | 有四張同一點數的牌。 | 10♣ 10♦ 10♥ 10♠ 9♥ |
3 | 滿堂紅 | Full House | 三張同一點數的牌,加一對其它點數的牌。 | 8♣ 8♦ 8♠ K♥ K♠ |
4 | 同花 | Flush | 五張同一花色的牌。 | A♠ K♠ 10♠ 9♠ 8♠ |
5 | 順子 | Straight | 五張順序的牌。 | K♦ Q♥ J♠ 10♦ 9♦ |
6 | 三條 | Three of a kind | 有三張同一點數的牌。 | J♣ J♥ J♠ K♦ 9♠ |
7 | 兩對 | Two Pairs | 兩張相同點數的牌,加另外兩張相同點數的牌。 | A♣ A♦ 8♥ 8♠ Q♠ |
8 | 一對 | One Pair | 兩張相同點數的牌。 | 9♥ 9♠ A♣ J♠ 8♥ |
9 | 無對 | Zilch | 不能排成以上組合的牌。 | A♦ Q♦ J♠ 9♣ 8♣ |
備註:和某知名遊戲《鬥地主》類似的,10 J Q K A可以組成順子,但是J Q K A 2不能組成。不過和《鬥地主》不同的是,A 2 3 4 5和2 3 4 5 6也可以組成順子。我們認為A 2 3 4 5是順子中最小的一個,而10 J Q K A是順子中最大的一個。
比較兩組牌的大小時,先按照上述規則比較大小,牌型編號小的牌組大。如果兩組牌的牌型編號相同,那麼按照牌型內牌的重要程度排序,同等重要程度的按照牌型大小排序,按照順序比較牌的大小,牌大的牌組大。
對於兩組牌的比較,點數優先,花色在後。(先比較所有牌的大小,若全部相同再比較花色。)
點數的順序為:A>K>Q>J>10>9>8>7>6>5>4>3>2。
注意:當五張手牌為5 4 3 2 A時,A可以看做最小的牌。此時牌型仍為順子,是順子裡面最小的一個。
花色的順序為:黑桃(♠)>紅心(♥)>梅花(♣)>方塊(♦)。
【輸入格式】
輸入檔名為 ptgiving.in。
輸入的第一行包含一個正整數T,表示有T組測試資料。
接下來有10*T行,每組測試資料包含10行。
每組資料的前5行每行用兩個整數描述一張cdy手上的牌。每行第一個數表示牌的數碼(1表示A,11表示J,12表示Q,13表示K),第二個數表示牌的花色(1表示黑桃,2表示紅心,3表示梅花,4表示方塊)。
後5行每行用兩個整數描述xy手上的牌,格式同上。
【輸出格式】
輸出檔名為ptgiving.out。
一共輸出T行,對於每組測試資料,輸出cdy或者xy,表示誰的牌比較大。
考場上打了兩個多小時的大模擬。
因為種種失誤從100變成40。
個人認為最主要的是寫一個比較優秀的排序。
這樣排完序之後直接按照每一張依次比。
還有注意順子的情況需要判斷12345這種情況。
排序的話,要保證牌數多的放在前面。
然後牌數一樣保證權值大的放在前面。
之後是顏色。
非常開心,在自己生日的這天衡水下起了雨。
noip2018加油。
生日快樂 王小呆
code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int wx=47;
inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
}
struct node{
int val,col;
friend bool operator < (const node & a,const node & b){
if(a.val==b.val)return a.col>b.col;
return a.val<b.val;
}//牌點數小在前,牌花色小在前
};
struct Node{
int tval[wx];
int tcol[wx];
node p[wx];
int flag;
}xy,cdy;
int t[wx];
bool Straight_Flush(Node wxd){
for(int i=1;i<=4;i++)if(wxd.tcol[i]>0&&wxd.tcol[i]<5)return false;//判斷每一種花色要麼是0要麼是1(同花)
if(wxd.p[1].val==1&&wxd.p[2].val==10&&wxd.p[3].val==11&&wxd.p[4].val==12&&wxd.p[5].val==13)return true;
//差點忘記判這個小東西
for(int i=1;i<=5;i++)
if(wxd.p[i].val-wxd.p[1].val!=i-1)return false;//判斷每一張牌是否形成等差數列(順)
return true;
}
bool Four_of_a_Kind(Node wxd){
for(int i=1;i<=13;i++)if(wxd.tval[i]==2||wxd.tval[i]==3)return false;//判斷有沒有出現牌數為2或3的,因為這是在判4帶1
//沒有的話,好像直接返回還不行,至少有一個4的 避免出現5個1這樣的情況
for(int i=1;i<=13;i++)if(wxd.tval[i]==4)return true;
return false;
}
bool Full_House(Node wxd){
for(int i=1;i<=13;i++)if(wxd.tval[i]==1||wxd.tval[i]==4)return false;//這是在判3帶2啊喂,有1或者4當然是不行了
//然後看一看有沒有3個的就可以了
for(int i=1;i<=13;i++)if(wxd.tval[i]==3)return true;
return false;
}
bool Flush(Node wxd){
for(int i=1;i<=4;i++)if(wxd.tcol[i]==5)return true;//同花:直接判有沒有五張同花色的就可以了
return false;
}
bool Straight(Node wxd){
//直接複製上面的挺好
if(wxd.p[1].val==1&&wxd.p[2].val==10&&wxd.p[3].val==11&&wxd.p[4].val==12&&wxd.p[5].val==13)return true;
for(int i=1;i<=5;i++)
if(wxd.p[i].val-wxd.p[1].val!=i-1)return false;
return true;
}
bool Three_of_a_kind(Node wxd){
for(int i=1;i<=13;i++)if(wxd.tval[i]==3)return true;//3帶2的上面已經判過了,所以這裡只判3就可以了
return false;
}
bool Two_Pairs(Node wxd){
//直接統計對的個數就行了吧。。
int re=0;
for(int i=1;i<=13;i++)if(wxd.tval[i]==2)re++;
if(re==2)return true;
return false;
}
bool One_Pair(Node wxd){
//同上
for(int i=1;i<=13;i++)if(wxd.tval[i]==2)return true;
return false;
}
int work(Node zmj){
if(Straight_Flush(zmj)) return 1; //同花順
if(Four_of_a_Kind(zmj)) return 2;
if(Full_House(zmj)) return 3;
if(Flush(zmj)) return 4;
if(Straight(zmj)) return 5;
if(Three_of_a_kind(zmj))return 6;
if(Two_Pairs(zmj)) return 7;
if(One_Pair(zmj)) return 8;
return 9;
}
bool cmp(node a,node b){
if(t[a.val]==t[b.val]&&a.val==b.val)return a.col<b.col;
if(t[a.val]==t[b.val])return a.val>b.val;
return t[a.val]>t[b.val];
}
void bu_huang_1(){
if((cdy.p[1].val==1&&cdy.p[2].val==2)||(xy.p[1].val==1&&xy.p[2].val==2)){//有一個是12345這樣的
if((cdy.p[1].val==1&&cdy.p[2].val==2))puts("xy");
else puts("cdy");
}
else{
for(int i=1;i<=5;i++)if(cdy.p[i].val==1)cdy.p[i].val=14;//先把1轉成權值大的14
for(int i=1;i<=5;i++)if(xy.p[i].val==1)xy.p[i].val=14;
sort(cdy.p+1,cdy.p+6);
sort(xy.p+1,xy.p+6);
if(cdy.p[5].val>xy.p[5].val)puts("cdy");//在比較最後一張牌的資訊
if(cdy.p[5].val<xy.p[5].val)puts("xy");
if(cdy.p[5].val==xy.p[5].val&&cdy.p[5].col<xy.p[5].col)puts("cdy");
if(cdy.p[5].val==xy.p[5].val&&cdy.p[5].col>xy.p[5].col)puts("xy");
}
}
void bu_huang(){
for(int i=1;i<=5;i++)if(cdy.p[i].val==1)cdy.p[i].val=14;//先把1轉成權值大的14
for(int i=1;i<=5;i++)if(xy.p[i].val==1)xy.p[i].val=14;
memset(t,0,sizeof t);
for(int i=1;i<=5;i++)t[cdy.p[i].val]++;
sort(cdy.p+1,cdy.p+6,cmp);
memset(t,0,sizeof t);
for(int i=1;i<=5;i++)t[xy.p[i].val]++;
sort(xy.p+1,xy.p+6,cmp);
for(int i=1;i<=5;i++){
if(cdy.p[i].val>xy.p[i].val){puts("cdy");return ;}
if(cdy.p[i].val<xy.p[i].val){puts("xy");return ;}
}
for(int i=1;i<=5;i++){
if(cdy.p[i].col<xy.p[i].col){puts("cdy");return ;}
if(cdy.p[i].col>xy.p[i].col){puts("xy");return ;}
}
}
void bu_huang_5(){//這個很難受。。。
if((cdy.p[1].val==1&&cdy.p[2].val==2)||(xy.p[1].val==1&&xy.p[2].val==2)){
if((cdy.p[1].val==1&&cdy.p[2].val==2)&&(xy.p[1].val==1&&xy.p[2].val==2)){
for(int i=5;i>=1;i--){
if(cdy.p[i].col<xy.p[i].col){
puts("cdy");return ;
}
if(cdy.p[i].col>xy.p[i].col){
puts("xy");return ;
}
}
}
if((cdy.p[1].val==1&&cdy.p[2].val==2))puts("xy");
if((xy.p[1].val==1&&xy.p[2].val==2))puts("cdy");
}
else{
for(int i=1;i<=5;i++)if(cdy.p[i].val==1)cdy.p[i].val=14;//先把1轉成權值大的14
for(int i=1;i<=5;i++)if(xy.p[i].val==1)xy.p[i].val=14;
memset(t,0,sizeof t);
for(int i=1;i<=5;i++)t[cdy.p[i].val]++;
sort(cdy.p+1,cdy.p+6,cmp);
memset(t,0,sizeof t);
for(int i=1;i<=5;i++)t[xy.p[i].val]++;
sort(xy.p+1,xy.p+6,cmp);
for(int i=1;i<=5;i++){
if(cdy.p[i].val>xy.p[i].val){puts("cdy");return ;}
if(cdy.p[i].val<xy.p[i].val){puts("xy");return ;}
}
for(int i=1;i<=5;i++){
if(cdy.p[i].col<xy.p[i].col){puts("cdy");return ;}
if(cdy.p[i].col>xy.p[i].col){puts("xy");return ;}
}
}
}
void you_dian_huang(){
if(cdy.flag==1)bu_huang_1();
if(cdy.flag==2)bu_huang();
if(cdy.flag==3)bu_huang();
if(cdy.flag==4)bu_huang();
if(cdy.flag==5)bu_huang_5();
if(cdy.flag==6)bu_huang();
if(cdy.flag==7)bu_huang();
if(cdy.flag==8)bu_huang();
if(cdy.flag==9)bu_huang();
}
void clear(){
memset(cdy.tval,0,sizeof cdy.tval);
memset(cdy.tcol,0,sizeof cdy.tcol);
memset(xy.tval,0,sizeof xy.tval);
memset(xy.tcol,0,sizeof xy.tcol);
memset(cdy.p,0,sizeof cdy.p);
memset(xy.p,0,sizeof xy.p);
}
int main(){
freopen("ptgiving.in","r",stdin);
freopen("ptgiving.out","w",stdout);
int T=read();
while(T--){
clear();
for(int i=1;i<=5;i++){
cdy.p[i].val=read(); cdy.p[i].col=read();
cdy.tval[ cdy.p[i].val ]++; cdy.tcol[ cdy.p[i].col ]++;
}
for(int i=1;i<=5;i++){
xy.p[i].val=read(); xy.p[i].col=read();
xy.tval[ xy.p[i].val ]++; xy.tcol[ xy.p[i].col ]++;
}
sort(cdy.p+1,cdy.p+6);
sort(xy.p+1,xy.p+6);
cdy.flag=work(cdy);
xy.flag=work(xy);
if(cdy.flag==xy.flag)you_dian_huang();
else {
if(cdy.flag<xy.flag)puts("cdy");
else puts("xy");
}
}
fclose(stdin);
fclose(stdout);
return 0;
}