UVA 207 PGA Tour Prize Money

知识补充:

①:ssprintf:

   int sprintf(char *str, const char *format, ...)
   发送格式化输出到 str 所指向的字符串。
   char str[80];

   sprintf(str, "Pi 的值 = %f", M_PI);
   puts(str);

②:strchr

   如果需要对字符串中的单个字符进行查找,
        那么应该使用 strchr 或 strrchr 函数。
        其中,strchr 函数原型的一般格式如下:
        char *strchr(const char *s, int c);
        它表示在字符串 s 中查找字符 c,
        返回字符 c 第一次在字符串 s 中出现的位置,
        如果未找到字符 c,则返回 NULL。也就是说,
        strchr 函数在字符串 s 中从前到后(或者称为从左到右)查找字符 c,
        找到字符 c 第一次出现的位置就返回,
        返回值指向这个位置,如果找不到字符 c 就返回 NULL。
        相对于 strchr 函数,strrchr 函数原型的一般格式如下:
        char *strrchr(const char *s, int c);
        与 strchr 函数一样,它同样表示在字符串 s 中查找字符 c,返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL。但两者唯一不  同的     是,strrchr 函数在字符串 s 中是从后到前(或者称为从右向左)查找字符 c,找到字符 c 第一次出现的位置就返回,返回值指向这个位   置。

③:sscanf

  Int sscanf( string str, string fmt, mixed var1, mixed var2 ... ); 
  int scanf( const char *format [,argument]... ); 

       sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。 简单地说就是输入的类型不同。

 

  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<cassert>
  8 using namespace std;
  9 
 10 const int n_cut = 70;
 11 const int maxn = 144;
 12 
 13 struct Player
 14 {
 15     char name[25];
 16     int amateur;//业余
 17     int sc[4];//4轮分数
 18     int sc36, sc72, dq;//前两局分数,和前4局分数,是否犯规
 19     int rnds;
 20 }players[maxn];
 21 
 22 double purse,p[70];//总金额和百分比 
 23 int n;//选手人数 
 24 
 25 bool cmp1(const Player& p1,const Player &p2)
 26 {
 27     if(p1.sc36<0&&p2.sc36<0)//equal
 28         return false;
 29     if(p1.sc36<0)//p1 DQ,p2 不DQ,把DQ的p1放后面 
 30         return false;
 31     if(p2.sc36<0)//p1 !DQ,p2 DQ
 32         return true;
 33     return p1.sc36<p2.sc36;
 34 }
 35 
 36 bool cmp2(const Player& p1,const Player & p2)
 37 {
 38     if(p1.dq&&p2.dq)//p1,p2都DQ
 39     {
 40         if(p1.rnds!=p2.rnds)//并列先比轮数 
 41             return p2.rnds<p1.rnds;//场数多放前面 
 42         if(p1.sc72!=p2.sc72)//比得分 
 43             return p1.sc72<p2.sc72;//得分少放前面 
 44         return strcmp(p1.name,p2.name)<0;//名字 
 45     } 
 46     if(p1.dq)//p1 DQ,p1排后面 
 47         return false;
 48     if(p2.dq)//p2 DQ,p2排后面 
 49         return true;
 50     if(p1.sc72!=p2.sc72)
 51         return p1.sc72<p2.sc72;
 52     return strcmp(p1.name,p2.name)<0;
 53 }
 54 
 55 void print_result()
 56 {
 57     printf("Player Name          Place     RD1  RD2");
 58     printf("  RD3  RD4  TOTAL     Money Won\n");
 59     printf("---------------------------------------");
 60     printf("--------------------------------\n");
 61     int i=0,pos=0;//pos所占百分比的下标
 62     
 63     while(i<n)
 64     {
 65         if(players[i].dq)//DQ
 66         {
 67             printf("%s           ",players[i].name);
 68             for(int j=0;j<players[i].rnds;j++)
 69             {
 70                 printf("%-5d",players[i].sc[j]);
 71             }
 72             for(int j=0;j<4-players[i].rnds;j++)
 73             {
 74                 printf("     ");
 75             }
 76             printf("DQ\n");
 77             i++;
 78             continue;
 79         }
 80         
 81         int j=i;
 82         int m=0;//并列的人数 
 83         bool have_money=false;
 84         double tot=0.0;
 85         while(j<n&&players[i].sc72==players[j].sc72)
 86         {
 87             if(!players[j].amateur)//成绩一样且不业余 
 88             {
 89                 m++;
 90                 if(pos<n_cut)
 91                 {
 92                     have_money=true;
 93                     tot+=p[pos++];
 94                 }
 95             }
 96             j++;
 97         }
 98         
 99         // print player [i,j) together because they have the same rank
100         int rank=i+1;//并列选手的名次 
101         double amout=purse*tot/m;
102          // if m=0, amount will be nan but we don't use it in that case :)
103         while(i<j)
104         {
105             printf("%s ", players[i].name);
106             char t[5];
107             sprintf(t,"%d%c",rank,m>1&&have_money&&!players[i].amateur?'T':' ');
108             printf("%-10s",t);
109             for(int k=0;k<4;k++)
110             {
111                 printf("%-5d",players[i].sc[k]);
112             }
113             
114             //打印总分和奖金
115             if(!players[i].amateur&&have_money)
116             {
117                 printf("%-10d",players[i].sc72);
118                 printf("$%9.2lf\n",amout/100.0);    
119             } 
120             else
121             {
122                 printf("%d\n",players[i].sc72);
123             }
124             i++;
125         }
126     }
127 }
128 
129 int main()
130 {
131     int T;//测试数目 
132     char s[40];
133     gets(s);
134     sscanf(s, "%d", &T);
135     while (T--)
136     {
137         gets(s);//取空行
138         gets(s);
139         sscanf(s,"%lf",&purse);
140         for(int i=0;i<n_cut;i++)
141         {
142             gets(s);
143             sscanf(s,"%lf",&p[i]);
144         }
145         //scanf("%d",&n);
146         gets(s);
147         sscanf(s,"%d",&n);//
148         assert(n <= 144);// 
149         for(int i=0;i<n;i++)
150         {
151              
152             gets(s);
153             strncpy(players[i].name,s,20);
154             players[i].name[20]=0;
155             players[i].amateur=0;
156             if(strchr(players[i].name,'*'))//给name赋值 
157                 players[i].amateur=-1;
158             //scores
159             players[i].sc36=players[i].sc72=players[i].dq=0;
160             memset(players[i].sc,-1,sizeof(players[i].sc));
161             //下面取分数
162             for(int j=0;j<4;j++)
163             {
164                 char t[5];
165                 for(int k=0;k<3;k++)
166                 {
167                     t[k]=s[20+j*3+k];//挨个取,取前三个成绩 
168                 }    
169                 t[3]='\0';
170                 //下面检查是否DQ,利用第四个成绩 
171                 if(!sscanf(t,"%d",&players[i].sc[j]))//两种可能:1.第四个是DQ,2.前面有DQ,此处没有数字 
172                 {
173                     players[i].rnds=j;
174                     players[i].dq=-1;
175                     if(j<2)
176                         players[i].sc36=-1;
177                     break;
178                 }
179                 else
180                 {
181                     players[i].sc72+=players[i].sc[j];
182                     if(j<2)
183                         players[i].sc36+=players[i].sc[j];
184                 }
185             } 
186         }
187         //第一次排序
188         sort(players,players+n,cmp1);//从小到大,前70名晋级 
189         assert(players[n_cut-1].sc36 >= 0);
190         for(int i=n_cut-1;i<n;i++)//看看第70名有没有并列的,修改n 
191         {
192             if(i==n-1||players[i].sc36!=players[i+1].sc36)
193             {
194                 n=i+1;//sort左闭右开,所以+1 
195                 break;    
196             }    
197         } 
198         
199         //第二次排序
200         sort(players,players+n,cmp2);
201         
202         //print_result
203         print_result(); 
204         
205         if(T)
206         printf("\n"); 
207     }
208     return 0;
209 }

 

posted @ 2019-02-12 18:34  付玬熙  阅读(266)  评论(0编辑  收藏  举报