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