这道题真的是搞心态的神仙题了,由于到最后还是晕晕乎乎+WA,所以就不多说了,直接贴代码。
题目链接:UVa 207
WA代码:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define DQ 99999
#define eps 1e-8
struct Player{
char name[30]; //姓名
int RD[4]; //四轮成绩
int RD_2; //前两轮成绩
int RD_all; //总成绩
int places; //名次
double prize; //奖金
bool is_pro; //是否为职业运动员
bool is_T; //是否并列
}players[1000];
bool cmp1(const Player& a, const Player& b) { //cmp1和cmp2都保证满轮数,所以不用考虑轮数比较
if (a.RD_2 != b.RD_2)
return a.RD_2 < b.RD_2;
return strcmp(a.name, b.name) < 0;
}
bool cmp2(const Player& a, const Player& b) {
if (a.RD_all != b.RD_all)
return a.RD_all < b.RD_all;
return strcmp(a.name, b.name) < 0;
}
bool cmp3(const Player& a, const Player& b) { //为末尾的DQ选手排序
int s1 = 0, s2 = 0;
for(int i=0;i<4;i++)
if (a.RD[i] == DQ) {
s1 = i;
break;
}
for(int i=0;i<4;i++)
if (b.RD[i] == DQ) {
s2 = i;
break;
}
if (s1 != s2)
return s1 > s2;
if (a.RD_all != b.RD_all)
return a.RD_all < b.RD_all;
return strcmp(a.name, b.name) < 0;
}
int len(int n) {
int sum = 0;
while (n > 0) {
n /= 10;
sum++;
}
return sum;
}
int main() {
int T, num;
double money, prop[100];
while (T--) {
memset(players, 0, sizeof(players));
memset(prop, 0, sizeof(prop));
cin >> money;
for (int i = 0; i < 70; i++)
cin >> prop[i];
cin >> num;
getchar();
for (int i = 0; i < num; i++) {
fgets(players[i].name, 20, stdin);
if (!strchr(players[i].name, '*')) //strchr用以在一个串中查找给定字符的第一个匹配处,找到则返回1
players[i].is_pro = true;
for (int j = 0; j < 4; j++) {
int flag = 0;
if (!scanf("%d",&players[i].RD[j])) {
players[i].RD[j] = DQ;
flag = 1;
}
if (j < 2)
players[i].RD_2 += players[i].RD[j];
players[i].RD_all += players[i].RD[j];
if (flag)
break;
}
char ch[45];
fgets(ch, 40, stdin);
}
sort(players, players + num, cmp1);
int pos = 0, pos2 = 0;
while (pos < min(num, 70) && players[pos].RD_2 < DQ) //将pos移动到最后一个没有犯规的选手的后一位上
pos++;
while (pos < num && players[pos].RD_2 == players[pos - 1].RD_2 && players[pos].RD_2 < DQ) //在num>70且第70位选手未犯规的情况下,将pos移动到与第70位选手并列的最后一位选手的后一位上
pos++;
sort(players,players+pos,cmp2);
while (pos2<num && pos2 <= pos && players[pos2].RD_all < DQ) //将pos2移动到最后一个在后两轮没有犯规的选手的后一位上或pos(晋级的最后一位选手的后一位)处
pos2++;
while (pos2 < num && players[pos2].RD_all == players[pos2 - 1].RD_all && players[pos2].RD_all < DQ)
pos2++;
if (pos2 != pos)
sort(players + min(pos,pos2), players + max(pos,pos2), cmp3);
int rank = 1, cur = 0, pos3, cont = 0;
while (cur < min(pos,pos2)) {
int sum = 0;
double sum_mon = 0;
for (pos3 = cur; players[pos3].RD_all == players[cur].RD_all; pos3++) {
if (players[pos3].is_pro) {
sum++;
sum_mon += prop[cont++];
}
}
if (sum)
sum_mon /= sum;
else
sum_mon /= 100;
for (int i = cur; i < pos3; i++) {
players[i].places = rank;
if (players[i].is_pro && sum) {
players[i].prize = sum_mon * money / 100.0 + eps;
if (sum > 1 && cont-sum<70)
players[i].is_T = true;
}
if (cont - sum >= 70)
players[i].is_pro = false;
}
int numb = pos3 - cur;
rank += numb;
cur += numb;
}
cout << "Player Name Place RD1 RD2 RD3 RD4 TOTAL Money Won" << endl;
cout << "-----------------------------------------------------------------------" << endl;
for (int i = 0; i < pos; i++) {
printf("%-20s", players[i].name); //输出name,不足二十位则在后面用空格填充
int N = 10;
if (players[i].RD_all < DQ) {
cout << players[i].places;
N -= len(players[i].places);
}
if (players[i].is_T) {
cout << "T";
N--;
}
for (int i = 0; i < N; i++) //???
cout << " ";
N = 4;
for (int j = 0; j < 4; j++) {
if (players[i].RD[j] != DQ)
printf("%-6d", players[i].RD[j]);
else {
N -= j;
break;
}
}
if (N == 4)
N = 0;
for (int i = 0; i < N; i++) //???
cout << " ";
if (N) {
cout << "DQ" << endl;
continue;
}
if (players[i].is_pro) {
printf("%-8d", players[i].RD_all);
printf("$%9.2lf", players[i].prize);
}
else
printf("%d", players[i].RD_all);
cout << endl;
}
if (T)
cout << endl;
}
return 0;
}