例题5-10 UVa207-PGA Tour Prize Money(WA)

这道题真的是搞心态的神仙题了,由于到最后还是晕晕乎乎+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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值