课程论文还在手搓?书匠策AI这套“四步傻瓜流程“让我直接真香了
2026/5/12 16:30:25
#)题解
本题是一个高尔夫球赛奖金分配问题。题目要求根据给定的总奖金(purse)、前707070名的奖金百分比、以及球员的比赛成绩,计算出最终获得奖金的球员名单及其应得的奖金金额。
主要规则如下:
DQ(取消资格)。*)不能获得奖金,其“赢得”的奖金顺延给下一位非业余球员。DQ,则只分配实际完赛的名次奖金。DQ球员(放在最后,总分栏填DQ)。定义一个结构体player存储每位球员的信息:
读取输入
money和前707070名的奖金百分比(转换为小数存储)。parseToPlayer解析成绩和业余标识。第一轮筛选(363636洞晋级)
第二轮筛选(727272洞完赛)
DQ列表。奖金分配
T。输出
DQ球员(按完成轮数降序、总成绩升序、姓名升序)。T仅当两个或以上非业余球员成绩相同时才添加。DQ球员的TOTAL列输出DQ,其余轮次成绩为空(不输出数字)。// PGA Tour Prize Money// UVa ID: 207// Verdict: Accepted// Submission Date: 2016-04-26// UVa Run Time: 0.050s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintDQ=-1;// 表示取消资格或未完成该轮structplayer{string name;// 球员姓名intrd1,rd2,rd3,rd4;// 四轮成绩inttotal;// 总成绩(36洞或72洞)intplace;// 最终排名intround;// 完成的轮数boolamateur;// 是否为业余球员booltie;// 是否为并列(仅非业余)boolprized;// 是否获得奖金doubleprize;// 奖金金额};boolprintBlankLine=false;// 控制用例间空行vector<player>players;// 所有球员vector<double>percents;// 前70名的奖金百分比(小数形式)doublemoney;// 总奖金// 按总成绩升序,相同则按姓名升序boolcmp(player a,player b){if(a.total==b.total)returna.name<b.name;elsereturna.total<b.total;}// 用于DQ球员排序:先按完成轮数降序,再按cmpboolcmp2(player a,player b){if(a.round==b.round)returncmp(a,b);elsereturna.round>b.round;}// 主处理函数:筛选、分配奖金、输出voidallocate(){if(printBlankLine)cout<<"\n";elseprintBlankLine=true;// 打印表头cout<<setw(21)<<left<<"Player Name";cout<<setw(10)<<left<<"Place";cout<<setw(5)<<left<<"RD1";cout<<setw(5)<<left<<"RD2";cout<<setw(5)<<left<<"RD3";cout<<setw(5)<<left<<"RD4";cout<<setw(10)<<left<<"TOTAL";cout<<"Money Won\n";cout<<"-----------------------------------------------------------------------\n";// ---- 36洞晋级筛选 ----vector<player>dq;vector<player>firstcut;for(inti=0;i<players.size();i++)if(players[i].round>=2){players[i].total=players[i].rd1+players[i].rd2;firstcut.push_back(players[i]);}sort(firstcut.begin(),firstcut.end(),cmp);// 取前70名(含并列)if(firstcut.size()>70){intlast;for(last=70;last<firstcut.size();last++)if(firstcut[last].total==firstcut[69].total)continue;elsebreak;firstcut.erase(firstcut.begin()+last,firstcut.end());}// ---- 72洞完赛筛选 ----vector<player>secondcut;for(inti=0;i<firstcut.size();i++){if(firstcut[i].round>=4){firstcut[i].total+=(firstcut[i].rd3+firstcut[i].rd4);firstcut[i].prized=false;firstcut[i].tie=false;secondcut.push_back(firstcut[i]);}elsedq.push_back(firstcut[i]);// 晋级但未完成全部四轮}sort(secondcut.begin(),secondcut.end(),cmp);// ---- 分配奖金百分比(跳过业余) ----for(inti=0,index=0;i<secondcut.size()&&index<70;i++)if(!secondcut[i].amateur){secondcut[i].prize=percents[index++];secondcut[i].prized=true;}// ---- 处理并列及最终奖金计算 ----for(inti=0,place=1;i<secondcut.size();){intcounter=0,prizedPlayers=0,noAmateurs=0;doubleprizeAllocate=0.0;// 统计相同成绩的球员while((i+counter)<secondcut.size()&&secondcut[i+counter].total==secondcut[i].total){if(!secondcut[i+counter].amateur&&secondcut[i+counter].prized)prizedPlayers++;if(!secondcut[i+counter].amateur)noAmateurs++;if(secondcut[i+counter].prized)prizeAllocate+=secondcut[i+counter].prize;counter++;}if(counter>1){if(prizedPlayers>0)prizeAllocate/=noAmateurs;// 平均分配百分比之和prizeAllocate*=money;// 换算为实际奖金for(intj=0;j<counter;j++){secondcut[i+j].place=place;if(!secondcut[i+j].amateur&&prizedPlayers>0){secondcut[i+j].tie=noAmateurs>1;// 多于1个非业余才加Tsecondcut[i+j].prized=true;secondcut[i+j].prize=prizeAllocate;}}place+=counter;i+=counter;}else{secondcut[i].place=place;secondcut[i].tie=false;secondcut[i].prize*=money;place++;i++;}}// ---- 输出获奖球员 ----for(inti=0;i<secondcut.size();i++){cout<<setw(21)<<left<<secondcut[i].name;string standing=to_string(secondcut[i].place)+(secondcut[i].tie?"T":"");cout<<setw(10)<<left<<standing;cout<<setw(5)<<left<<secondcut[i].rd1;cout<<setw(5)<<left<<secondcut[i].rd2;cout<<setw(5)<<left<<secondcut[i].rd3;cout<<setw(5)<<left<<secondcut[i].rd4;if(secondcut[i].prized){cout<<setw(10)<<left<<secondcut[i].total;cout<<"$";cout<<setw(9)<<right<<fixed<<setprecision(2)<<secondcut[i].prize;}elsecout<<secondcut[i].total;cout<<"\n";}// ---- 输出DQ球员 ----// 先计算已完成的轮次总分(用于排序)for(inti=0;i<dq.size();i++)dq[i].total+=dq[i].rd3!=DQ?dq[i].rd3:0;sort(dq.begin(),dq.end(),cmp2);for(inti=0;i<dq.size();i++){cout<<setw(21)<<left<<dq[i].name;cout<<setw(10)<<left<<"";cout<<setw(5)<<left<<(dq[i].rd1!=DQ?to_string(dq[i].rd1):"");cout<<setw(5)<<left<<(dq[i].rd2!=DQ?to_string(dq[i].rd2):"");cout<<setw(5)<<left<<(dq[i].rd3!=DQ?to_string(dq[i].rd3):"");cout<<setw(5)<<left<<(dq[i].rd4!=DQ?to_string(dq[i].rd4):"");cout<<"DQ\n";}}// 去除字符串首尾空白stringtrim(string line){while(line.length()&&isblank(line.back()))line.erase(line.end()-1);while(line.length()&&isblank(line.front()))line.erase(line.begin());returnline;}// 解析一行输入为player结构体playerparseToPlayer(string line){// 确保长度至少32字符,不足补空格while(line.length()<32)line+=' ';player x;x.name=line.substr(0,20);x.amateur=trim(x.name).back()=='*';// 名字末尾有*表示业余x.rd1=DQ;x.rd2=DQ;x.rd3=DQ;x.rd4=DQ;x.round=0;string rd1=trim(line.substr(20,3));string rd2=trim(line.substr(23,3));string rd3=trim(line.substr(26,3));string rd4=trim(line.substr(29,3));// 逐轮解析,遇到DQ则停止if(rd1!="DQ"){x.rd1=stoi(rd1);x.round++;}elsereturnx;if(rd2!="DQ"){x.rd2=stoi(rd2);x.round++;}elsereturnx;if(rd3!="DQ"){x.rd3=stoi(rd3);x.round++;}elsereturnx;if(rd4!="DQ"){x.rd4=stoi(rd4);x.round++;}returnx;}intmain(){cin.tie(0);cin.sync_with_stdio(false);intcases=0;cin>>cases;while(cases--){players.clear();percents.clear();cin>>money;doublepercent;for(inti=1;i<=70;i++){cin>>percent;percents.push_back(percent/100.0);// 转换为小数}inttotalPlayers;cin>>totalPlayers;cin.ignore();string line;for(inti=1;i<=totalPlayers;i++){getline(cin,line);players.push_back(parseToPlayer(line));}allocate();}return0;}