日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SJTU OJ 3046 足球 题解

發布時間:2025/3/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SJTU OJ 3046 足球 题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

3046. 足球

Description

眾所周知,一只足球隊由11球員組成,其中有一名守門員和一名隊長。 現在,有22人組成的一個候選名單,從中要選出11人參加比賽。選拔規則如下: 首先提供一個陣型,例如,4-4-2。第一個4表示有4名后衛,第二個4表示有4名中場,第三個2表示有2名前鋒。當然,還有一個位置就是留給守門員的。 每個人都有自己唯一能打的位置(前鋒、中場、后衛、守門員)。在每個位置上,以球員的編號為關鍵字,從小到大依次選取。 選出球隊后還要選出隊長。隊長是球隊中參加比賽次數最多的球員。如果有并列,取編號較大的球員做隊長。

Input Format

前22行每行按如下格式表示出一名球員的信息: Number?Name?Role?year1-year’1?year2-year’2?… 整數Number(<=100)是該球員編號。字符串Name(length<=20)是該球員名字。字符Role是該球員所能打的位置(S前鋒、M中場、D后衛、G守門員)。每一對yeari-year’i(yeari<=year’i)?表示該球員效力的時間段,例如2001-2002表示該球員效力了兩年2001年和2002年。至少有1對年份,最多20對年份。年份是一個四位數。保證任意兩段年份不會重疊。球員的編號在球隊中是唯一的。 第23行給出一個陣型,例如4-4-2。保證陣型有且僅有3個正整數組成,且和等于10。例如,4-3-2-1是不合法的。

Output Format

輸出選出的11名球員,每一行包括球員編號,姓名,場上所打位置。之間用一個空格隔開。球員按守門員、后衛、中場、前鋒的順序排序,相同位置按編號從小到大排序。如果一名球員是隊長,那么無論他打什么位置,都放在序列的第一個。如果無法找出11個滿足條件的球員,輸出“IMPOSSIBLE?TO?ARRANGE”。

Sample Input

9?PlayerA?M?2000-2001?2003-2006 2?PlayerB?M?2004-2006 10?PlayerC?D?2001-2005 1?PlayerD?D?2000-2001?2002-2004 11?PlayerE?S?2003-2006 8?PlayerF?M?2005-2006 22?PlayerG?S?2005-2006 25?PlayerH?G?2000-2001?2002-2003?2005-2006 6?PlayerI?D?2003-2006 26?PlayerJ?D?2003-2004?2000-2001 18?PlayerK?M?2003-2004 19?PlayerL?M?2000-2001?2003-2006 7?PlayerM?S?2003-2006?1999-2001 21?PlayerN?S?2003-2006 13?PlayerO?S?2005-2006 15?PlayerP?G?2001-2006 14?PlayerQ?D?2003-2004 5?PlayerR?S?2000-2005 20?PlayerS?G?2000-2002?2003-2003 12?PlayerT?M?2004-2005 3?PlayerU?D?2000-2005 4?PlayerZ?M?2001-2004 4-4-2

Sample Output

7?PlayerM?S 15?PlayerP?G 1?PlayerD?D 3?PlayerU?D 6?PlayerI?D 10?PlayerC?D 2?PlayerB?M 4?PlayerZ?M 8?PlayerF?M 9?PlayerA?M 5?PlayerR?S

Limits

Time limit: 1000ms, memory limit: 50000kb.


===============================================================

題解正文

??? ===============================================================

  • 題目分析:

    首先我們要知道這道題目給了什么信息:

  • 這是張由22個球員構成的表。

  • 每個主球運動員都有 編號(唯一)、名字(沒有用)、位置(D M S G)、年份(這個年份純粹是搞出來糊弄人的,我們只要通過一定手段算出來到底有多少年即可)

  • 這題很好的地方是年份一定是四位數并且一定是長度為9的字符串:XXXX-XXXX,這個非常便于我們計算該運員干了多少年,干的年份越久表示參加的比賽越多 = =。

  • 輸出的要求其實也很簡單,滿足陣型是首要條件,接下來是選取相應的人,注意到同位置選取編號小的;

  • 選隊長時優先選年份多的,再次是編號大的(和上面不同)。

  • 算法實現:

  • 輸入

  • 考慮到運動員這一獨立的對象,又懶得寫類,于是用struct來構造一個player,這個struct叫ply

  • struct?ply{int?num;??//編號string?name;?//名字char?pst;?//位置int?years;?//年份bool?used;?//是否已經被選取,必要性不太大,保險起見而已 }players[22],team[11];?//左邊是備選的22個備胎,右邊是被選中的11個孩子
  • 上面提到的pst其實用枚舉類型更好,直接給那幾個位置賦G0 D1 M2 S3 這樣輸出時排列非常方便

  • 輸入流處理:

  • void?init() {cin?>>?players[0].num;?//這里可以看到我編號是額外處理的,這是因為讀取年份時為了簡便string?tmp;????????????//不得不多讀一個字符串,導致下一個球員的編號被讀入了tmp中for(int?i?=?0;?i?<?22;?++i){cin?>>?players[i].name??//直接存就好了>>players[i].pst;players[i].years?=?0;while(cin?>>?tmp?&&?tmp.length()?==?9)?//這就是為了及時停下來,但無可避免地{??????????????????????????????????????//讀取了下一個球員的編號int?a,?b;a?=?1000?*?(tmp[0]?-?'0')?+???????//計算年份100?*?(tmp[1]?-?'0')?+10?*?(tmp[2]?-?'0')?+?(tmp[3]?-?'0');b?=?1000?*?(tmp[5]?-?'0')?+100?*?(tmp[6]?-?'0')?+10?*?(tmp[7]?-?'0')?+?(tmp[8]?-?'0');players[i].years?+=?(b?-?a)?+?1;?//注意這個加一,小學常見的應用題陷阱}if(i?<?21)?players[i+1].num?=?(int)atof(tmp.c_str());//string直接轉成intplayers[i].used?=?0;?//初始化}sort(players,?players?+?22,?cmp1);?//排序優先位置升序,其次編號升序cin?>>?tmp;D?=?tmp[0]?-?'0';M?=?tmp[2]?-?'0';S?=?tmp[4]?-?'0'; }
  • 詳細講一下cmp的使用,我使用了三個cmp,分別有不同的用處,他們極大地維護了代碼的簡潔和準確

  • inline?bool?cmp1(ply?a,?ply?b) {??//優先位置升序,其次編號升序if(a.pst?==?b.pst)else?return?a.num?<?b.num;else?return?a.pst?<?b.pst; } //選隊長專用 inline?bool?cmp2(ply?a,?ply?b) {????//優先年份,年份一樣按大序號優先if(a.years?==?b.years?)?return?a.num?>?b.num;else?return?a.years?>?b.years; }//最后除了隊長之外的人進行排序 inline?bool?cmp3(ply?a,?ply?b) {if(a.pst?==?'G')return?1;//這兩條確保后衛排在最前面if(b.pst?==?'G')return?0;else//恰好利用了ascii中D?<?M?<?S?這一原則?不過如果輸出順序不按GDMS?我們也可以通過//enum來安排順序值if(a.pst?==?b.pst)?return?a.num?<?b.num;else?return?a.pst?<?b.pst;}
  • 選拔

  • 選拔就比較簡單了,主要是用了一個變量t來引導球員儲存到team中并且計算一共有多少球員滿足要求,當且僅當t==11時滿足要求,因此可以直接用t來判斷是否有解,我第一次提交就是忘記考慮無解的情況了

  • 另外輸入的時候讀取了四個位置所要求的值(當然G默認為1)通過while循環達到讀取的目的,不會漏掉也不會多取。

  • 具體請看最終代碼

  • 輸出

    輸出很簡單了。如果有解就對team數組進行排序,然后打印出來。無解就輸出那句話即可。

  • 代碼送上,有很多不足,大家看看就好~歡迎討論

  • #include?<iostream> #include?<string> #include?<vector> #include?<algorithm> #include<stdlib.h> #include<stdio.h>using?namespace?std;struct?ply{int?num;string?name;char?pst;int?years;bool?used; }players[22],team[11]; int?D,?M,?S,?G,?L; bool?flag?=?1; inline?bool?cmp1(ply?a,?ply?b) {if(a.pst?==?b.pst){if(a.num?==?b.num){if(a.years?==?b.years)?return?a.name?<?b.name;else?return?a.years?>?b.years;}else?return?a.num?<?b.num;}else?return?a.pst?<?b.pst; } inline?bool?cmp2(ply?a,?ply?b) {if(a.years?==?b.years?)?return?a.num?>?b.num;else?return?a.years?>?b.years; }inline?bool?cmp3(ply?a,?ply?b) {if(a.pst?==?'G')return?1;if(b.pst?==?'G')return?0;elseif(a.pst?==?b.pst)?return?a.num?<?b.num;else?return?a.pst?<?b.pst;} void?init() {cin?>>?players[0].num;string?tmp;for(int?i?=?0;?i?<?22;?++i){cin?>>?players[i].name>>players[i].pst;players[i].years?=?0;while(cin?>>?tmp?&&?tmp.length()?==?9){int?a,?b;a?=?1000?*?(tmp[0]?-?'0')?+100?*?(tmp[1]?-?'0')?+10?*?(tmp[2]?-?'0')?+?(tmp[3]?-?'0');b?=?1000?*?(tmp[5]?-?'0')?+100?*?(tmp[6]?-?'0')?+10?*?(tmp[7]?-?'0')?+?(tmp[8]?-?'0');players[i].years?+=?(b?-?a)?+?1;}if(i?<?21)?players[i+1].num?=?(int)atof(tmp.c_str());players[i].used?=?0;}sort(players,?players?+?22,?cmp1);cin?>>?tmp;D?=?tmp[0]?-?'0';M?=?tmp[2]?-?'0';S?=?tmp[4]?-?'0'; } void?select() {int?t?=?0;for(int?i?=?0;?i?<?22;?++i){while(D?&&?players[i].pst?==?'D'){team[t++]?=?players[i];++i,?--D;}if(players[i].pst?==?'G')team[t++]?=?players[i];while(players[i].pst?==?'G')++i;while(M?&&?players[i].pst?==?'M'){team[t++]?=?players[i];++i,?--M;}while(S?&&?players[i].pst?==?'S'){team[t++]?=?players[i];++i,?--S;}}if(t?==?11){sort(team,?team?+?11,?cmp2);sort(team?+?1,?team?+?11,?cmp3);}else?flag?=?0; } int?main() {init();select();if(flag)for(int?i?=?0;?i?<?11;?++i)cout<<team[i].num<<"?"<<team[i].name<<"?"<<team[i].pst<<endl;else?cout<<"IMPOSSIBLE?TO?ARRANGE"<<endl;}





    轉載于:https://my.oschina.net/xueyang/blog/288014

    總結

    以上是生活随笔為你收集整理的SJTU OJ 3046 足球 题解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。