題目描述
瑞神HRZ因爲疫情在家閒得無聊,同時他又非常厲害,所有的課對他來說都是水一水就能拿A+,所以他無聊,找來了另外三個人:咕咕東,騰神以及zjm來打牌(天下苦瑞神久矣)。
顯然,牌局由四個人構成,圍成一圈。我們稱四個方向爲北 東 南 西。對應的英文是North,East,South,West。遊戲一共由一副撲克,也就是52張構成。開始,我們指定一位發牌員(東南西北中的一個,用英文首字母標識)開始發牌,發牌順序爲順時針,發牌員第一個不發自己,而是發他的下一個人(順時針的下一個人)。這樣,每個人都會拿到13張牌。
現在我們定義牌的順序,首先,花色是(梅花)<(方片)<(黑桃)<(紅桃),(輸入時,我們用C,D,S,H分別表示梅花,方片,黑桃,紅桃,即其單詞首字母)。對於牌面的值,我們規定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
現在你作爲上帝,你要從小到大排序每個人手中的牌,並按照給定格式輸出。(具體格式見輸出描述和樣例輸出)。
輸入
輸出多組數據發牌的結果,每組數據之後需要額外多輸出一個空行!!!!! 每組數據應該由24行的組成,輸出按照順時針方向,始終先輸出South Player的結果,每位玩家先輸出一行即玩家名稱(東南西北),接下來五行,第一行和第五行輸出固定格式(見樣例),第二行和第四行按順序和格式輸出數值(見樣例),第三行按順序和格式輸出花色(見樣例)。 |
輸出
根據這些學生的得分現狀,輸出一個實時排名。實時排名顯然先按AC題數的多少排,多的在前,再按時間分的多少排,少的在前,如果湊巧前兩者都相等,則按名字的字典序排,小的在前。每個學生佔一行,輸出名字(10個字符寬),做出的題數(2個字符寬,右對齊)和時間分(4個字符寬,右對齊)。名字、題數和時間分相互之間有一個空格。數據保證可按要求的輸出格式進行輸出。 |
樣例輸入
樣例輸出
思路
綜述
該題涉及到的知識:
1)多關鍵字排序
對於多關鍵字排序的題目,可以構造結構體P,重載小於號,再構造優先隊列priority_queue<P>,從而達到排序的目的;
2)map的利用
因爲不同的花色,代表的大小不同,但是代表花色的字母代號並不是按照ASCII碼順序排列,(梅花)<(方片)<(黑桃)<(紅桃),(輸入時,我們用C,D,S,H分別表示梅花,方片,黑桃,紅桃,即其單詞首字母)所以可以如下操作:
map<char,int> mp;
mp['C'] = 1;
mp['D'] = 2;
mp['S'] = 3;
mp['H'] = 4;
對於牌號碼的大小也相同:2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A
mp['2'] = 1;
mp['3'] = 2;
mp['4'] = 3;
mp['5'] = 4;
mp['6'] = 5;
mp['7'] = 6;
mp['8'] = 7;
mp['9'] = 8;
mp['T'] = 9;
mp['J'] = 10;
mp['Q'] = 11;
mp['K'] = 12;
mp['A'] = 13;
過程
結構體:
struct P {
char card;//花色
char value;//數值
bool operator < (const P &p)const{
if(card!=p.card) return mp[card]>mp[p.card];//先按照花色排序
return mp[value]>mp[p.value];//再按照數值排序
}
};
step1:
接收發牌人,記錄其編號
cin>>x;
int first;
for(i=0;i<=3;i++)
if(mp2[i]==x) first = i;
step2:
接收所有牌,並且分發給四個人
四個人的牌存在優先隊列數組內:priority_queue<P> pai[4];
fapai(int):記錄下一張牌應發的人
string s1,s2;
cin>>s1>>s2;
s1+=s2;
int fapai = (first+1)%4;//從發牌人下一個開始
P nextcard;
for(i=0;i<s1.size();i++){
nextcard.card = s1[i];
nextcard.value = s1[++i];
pai[fapai].push(nextcard);
fapai=(fapai+1) % 4;//構成循環
}
step3:
輸出
因爲每一個優先隊列已經按順序排好,所以只需要順序輸出即可
對每個人:
分三波:牌號–>花色->牌號
構造結構體數組
struct P term[13];
第一次輸出牌號的時候,順便記錄所有牌,第二三次順序輸出即可;
出現的小問題
一
sizeof和strlen的應用
- strlen() 時函數,他在程序運行時才能計算。它的參數類型要求時 char *,且必須是以’/0’結尾。數組在傳入時已經退化爲指針。它的作用是返回數組中字符串的長度。
- sizeof()時運算符,它在程序編譯時就已經計算好了,用於計算數據空間的字節數。所以它不能用於返回動態分配的內存空間大小,常用於靜態分配的類型,對象,結構或數組所佔的空間。返回值和他們所存儲的內容沒有關係。
下圖是dev中的輸出:
下三圖是VS中的輸出:
所以,strlen()來求解字符數組,並不是很好的選擇。
二
因爲優先隊列輸出完後,爲空。不能再從頭輸出一遍。但是如果再構造一個優先隊列,採用複製構造函數。這樣雖然可以正確輸出,但是時間複雜度高,結果是超時;
所以,構造了一個結構體數組,這樣後兩遍便不需要再構造優先隊列。
代碼
#include <iostream>
#include <map>
#include <queue>
#include <string>
using namespace std;
map<char,int> mp;
struct P {
char card;
char value;
bool operator < (const P &p)const{
if(card!=p.card) return mp[card]>mp[p.card];
return mp[value]>mp[p.value];
}
};
int main(){
map<int,char> mp2;
mp2[0]='N';
mp2[1]='E';
mp2[2]='S';
mp2[3]='W';
mp['C'] = 1;
mp['D'] = 2;
mp['S'] = 3;
mp['H'] = 4;
mp['2'] = 1;
mp['3'] = 2;
mp['4'] = 3;
mp['5'] = 4;
mp['6'] = 5;
mp['7'] = 6;
mp['8'] = 7;
mp['9'] = 8;
mp['T'] = 9;
mp['J'] = 10;
mp['Q'] = 11;
mp['K'] = 12;
mp['A'] = 13;
int n,i,j,k;
char x;
priority_queue<P> pai[4];
while(1){
cin>>x;
if(x=='#')break;
int first;
for(i=0;i<=3;i++)
if(mp2[i]==x) first = i;
string s1,s2;
cin>>s1>>s2;
s1+=s2;
int fapai = (first+1)%4;
P nextcard;
for(i=0;i<s1.size();i++){
nextcard.card = s1[i];
nextcard.value = s1[++i];
pai[fapai].push(nextcard);
fapai=(fapai+1) % 4;
}
// 輸出
P term[13];
int sx;
cout<<"South player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[2].top().card;
term[sx].value = pai[2].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[2].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<"West player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[3].top().card;
term[sx].value = pai[3].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[3].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<"North player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[0].top().card;
term[sx].value = pai[0].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[0].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<"East player:"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
for(sx=0;sx<13;sx++){
term[sx].card = pai[1].top().card;
term[sx].value = pai[1].top().value;
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
pai[1].pop();
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"| "<<term[sx].card<<" ";
}
cout<<"|"<<endl;
for(sx=0;sx<13;sx++){
cout<<"|"<<term[sx].value<<" "<<term[sx].value;
}
cout<<"|"<<endl;
cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
cout<<endl;
}
}