• UVA 207 PGA Tour Prize Money


    题目链接:https://vjudge.net/problem/UVA-207

    题目翻译摘自《算法禁赛入门经典》

    题目大意

      你的任务是为PGA(美国职业高尔夫球协会)巡回赛计算奖金。巡回赛分为4轮,其中 所有选手都能打前两轮(除非中途取消资格),得分相加(越少越好),前70名(包括并列)晋级(make the cut)。所有晋级选手再打两轮,前70名(包括并列)有奖金。组委会事 先会公布每个名次能拿的奖金比例。例如,若冠军比例是18%,总奖金是$1000000,则冠军 奖金是$180000。

      输入保证冠军不会并列。如果第 k 名有 n 人并列,则第 k~n+k - 1 名的奖金比例相加后平均分给这 n 个人。如果 n+k - 1 超过 70,则第 k~70 名的奖金比例相加后平均分给这 n 个人。奖金四舍五入到美分。所有业余选手不得奖金。例如,若业余选手得了第 3 名,则第 4 名会拿第 3 名的奖金比例。如果没取消资格的非业余选手小于70名,则剩下的奖金就不发了。

      输入第一行为数据组数。每组数据前有一个空行,然后分为两部分。第一部分有 71 行 (各有一个实数),第一行为总奖金,第 i+1 行为第i名的奖金比例。比例均保留 4 位小数, 且总和为100%。第 72 行为选手数(最多144),然后每行一个选手。

      业余选手名字后会有一个“*”。犯规选手在犯规的那一轮成绩为DQ,并且后面不再有其他成绩。但是只要没犯规,即使没有晋级,也会给出4轮成绩(虽然在实际比赛中没晋级的 选手只会有两个成绩)。输入保证至少有70个人晋级

      输出应包含所有晋级到后半段(make the cut)的选手。输出信息包括:选手名字、排 名、各轮得分、总得分以及奖金数。没有得奖则不输出,若有奖金,即使奖金是$0.00也要 输出,保留两位小数)。如果此名次至少有两个人获得奖金,应在名次后面加“T”。犯规选 手列在最后,总得分为DQ,名次为空。如果有并列,则先按轮数排序,然后按各轮得分之 和排序,最后按名字排序。两组数据的输出之间用一个空格隔开。

    分析

      uDebug 上有误,输入输出要求得按照题目来。
      没什么难度,重点题目里我都标出来了,就是输入输出较烦。

    代码如下

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
      5 #define Rep(i,n) for (int i = 0; i < (n); ++i)
      6 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
      7 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
      8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
      9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
     10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
     12  
     13 #define pr(x) cout << #x << " = " << x << "  "
     14 #define prln(x) cout << #x << " = " << x << endl
     15  
     16 #define LOWBIT(x) ((x)&(-x))
     17  
     18 #define ALL(x) x.begin(),x.end()
     19 #define INS(x) inserter(x,x.begin())
     20  
     21 #define ms0(a) memset(a,0,sizeof(a))
     22 #define msI(a) memset(a,inf,sizeof(a))
     23 #define msM(a) memset(a,-1,sizeof(a))
     24 
     25 #define MP make_pair
     26 #define PB push_back
     27 #define ft first
     28 #define sd second
     29  
     30 template<typename T1, typename T2>
     31 istream &operator>>(istream &in, pair<T1, T2> &p) {
     32     in >> p.first >> p.second;
     33     return in;
     34 }
     35  
     36 template<typename T>
     37 istream &operator>>(istream &in, vector<T> &v) {
     38     for (auto &x: v)
     39         in >> x;
     40     return in;
     41 }
     42  
     43 template<typename T1, typename T2>
     44 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
     45     out << "[" << p.first << ", " << p.second << "]" << "
    ";
     46     return out;
     47 }
     48 
     49 inline int gc(){
     50     static const int BUF = 1e7;
     51     static char buf[BUF], *bg = buf + BUF, *ed = bg;
     52     
     53     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
     54     return *bg++;
     55 } 
     56 
     57 inline int ri(){
     58     int x = 0, f = 1, c = gc();
     59     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
     60     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
     61     return x*f;
     62 }
     63 
     64 template<class T>
     65 inline string toString(T x) {
     66     ostringstream sout;
     67     sout << x;
     68     return sout.str();
     69 }
     70 
     71 inline int toInt(string s) {
     72     int v;
     73     istringstream sin(s);
     74     sin >> v;
     75     return v;
     76 }
     77  
     78 typedef long long LL;
     79 typedef unsigned long long uLL;
     80 typedef pair< double, double > PDD;
     81 typedef pair< int, int > PII;
     82 typedef pair< int, PII > PIPII;
     83 typedef pair< string, int > PSI;
     84 typedef pair< int, PSI > PIPSI;
     85 typedef set< int > SI;
     86 typedef set< PII > SPII;
     87 typedef vector< int > VI;
     88 typedef vector< VI > VVI;
     89 typedef vector< SI > VSI;
     90 typedef vector< PII > VPII;
     91 typedef map< int, int > MII;
     92 typedef map< int, string > MIS;
     93 typedef map< int, PII > MIPII;
     94 typedef map< PII, int > MPIII;
     95 typedef map< string, int > MSI;
     96 typedef map< string, string > MSS;
     97 typedef map< PII, string > MPIIS;
     98 typedef map< PII, PII > MPIIPII;
     99 typedef multimap< int, int > MMII;
    100 typedef multimap< string, int > MMSI;
    101 //typedef unordered_map< int, int > uMII;
    102 typedef pair< LL, LL > PLL;
    103 typedef vector< LL > VL;
    104 typedef vector< VL > VVL;
    105 typedef priority_queue< int > PQIMax;
    106 typedef priority_queue< int, VI, greater< int > > PQIMin;
    107 const double EPS = 1e-8;
    108 const LL inf = 0x7fffffff;
    109 const LL infLL = 0x7fffffffffffffffLL;
    110 const LL mod = 1e9 + 7;
    111 const int maxN = 1e4 + 7;
    112 const LL ONE = 1;
    113 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
    114 const LL oddBits = 0x5555555555555555;
    115 
    116 struct Player{
    117     string name;
    118     int rank = 0, sc[4], totS = 0;
    119     bool isAmateur = false, isTied = false, isDQ = false, hasMoney = false;
    120     double bonus = 0;
    121     
    122     Player() {}
    123     Player(string s) {
    124         string tmp;
    125         name = s.substr(0, 20);
    126         if(name.find('*') != string::npos) isAmateur = true;
    127         
    128         Rep(i, 4) sc[i] = 666666; // 方便排序 
    129         
    130         Rep(i, 4) {
    131             tmp = s.substr(21 + i * 3, 2);
    132             if(tmp == "DQ") {
    133                 isDQ = true;
    134                 break;
    135             }
    136             else sc[i] = toInt(tmp);
    137         }
    138         
    139         Rep(i, 4) totS += sc[i];
    140     }
    141     
    142     bool operator< (const Player &x) const {
    143         if(totS == x.totS) return name < x.name;
    144         return totS < x.totS;
    145     }
    146     
    147     void print() {
    148         if(isDQ) {
    149             name.resize(31, ' ');
    150             cout << name;
    151             Rep(i, 4) {
    152                 if(sc[i] != 666666) printf("%-5d", sc[i]);
    153                 else printf("     ");
    154             }
    155             printf("DQ
    ");
    156             return;
    157         }
    158         
    159         name += " " + toString(rank);
    160         if(isTied && hasMoney) name.PB('T'); // 只有并列且拿钱才需要加 T 
    161         name.resize(31, ' ');
    162         cout << name;
    163         
    164         Rep(i, 4) printf("%-5d", sc[i]);
    165         
    166         if(hasMoney) printf("%-10d$%9.2f
    ", totS, bonus / 100 + EPS);
    167         else printf("%d
    ", totS);
    168     }
    169 };
    170 Player p[150];
    171 int num;
    172 
    173 inline bool cmp(const Player &x, const Player &y) {
    174     return x.sc[0] + x.sc[1] < y.sc[0] + y.sc[1];
    175 }
    176 
    177 int T;
    178 double totM, preRate[71];
    179 
    180 int main(){
    181     //freopen("MyOutput.txt","w",stdout);
    182     //freopen("input.txt","r",stdin);
    183     //INIT();
    184     scanf("%d
    ", &T);
    185     while(T--) {
    186         scanf("%lf
    ", &totM);
    187         For(i, 1, 70) {
    188             scanf("%lf
    ", &preRate[i]);
    189             preRate[i] += preRate[i - 1];
    190         }
    191         
    192         scanf("%d
    ", &num);
    193         For(i, 1, num) {
    194             string str;
    195             getline(cin, str);
    196             p[i] = Player(str);
    197         }
    198         sort(p + 1, p + 1 + num, cmp);
    199         
    200         // 选前 70 名 
    201         For(i, 71, num) {
    202             if(p[i].sc[0] + p[i].sc[1] != p[i - 1].sc[0] + p[i - 1].sc[1]) {
    203                 num = i - 1;
    204                 break;
    205             }
    206         }
    207         
    208         sort(p + 1, p + 1 + num);
    209         
    210         int i = 1, pcnt = 0; // pcnt 为已经给过奖金的人数 
    211         while(i <= num) {
    212             if(p[i].isDQ) break;
    213             int j = i - 1, cnt = 0;
    214             
    215             while(j + 1 <= num && p[j + 1].totS == p[i].totS) if(!p[++j].isAmateur) ++cnt;
    216             
    217             // [i, j] 为分数相同的区间,cnt记录这区间中非业余的人数 
    218             For(k, i, j) {
    219                 p[k].rank = i;
    220                 if(cnt >= 2 && !p[k].isAmateur) p[k].isTied = true;
    221                 
    222                 if(cnt && pcnt < 70 && !p[k].isAmateur) {
    223                     p[k].hasMoney = true;
    224                     p[k].bonus = totM * (preRate[min(pcnt + cnt, 70)] - preRate[pcnt]) / cnt;
    225                 }
    226             }
    227             i = j + 1;
    228             pcnt += cnt;
    229         }
    230         
    231         printf("Player Name          Place     RD1  RD2  RD3  RD4  TOTAL     Money Won
    ");
    232         printf("-----------------------------------------------------------------------
    ");
    233         i = 1;
    234         while(i <= num) p[i++].print();
    235         if(T) printf("
    ");
    236     }
    237     return 0;
    238 }
    View Code
  • 相关阅读:
    Quartus II 12.0傻瓜版安装教程(附下载链接)
    MathType 免费版安装教程(附下载链接)
    Matlab与Visual Studio 安装和联合编译配置(附下载链接)
    操作系统的概述
    Sublime Text 3 安装,C/C++代码的编译运行以及代码格式化的配置 (附下载链接)
    DSP中的DELAY_US ( )函数存放在FLASH下执行在RAM中的方法
    vtk:如何利用鼠标交会三维模型,获取交点坐标?
    进一步完善了近景摄影测量和低空数据处理软件!
    SURF算法速度更快!
    vtk:如何使用鼠标选中多个点?
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/11061723.html
Copyright © 2020-2023  润新知