知识补充:
①: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 }