1. 程式人生 > 其它 >CF19A World Football Cup 題解

CF19A World Football Cup 題解

CF19A World Football Cup 題解

Content

\(n\) 個球隊參加一場足球比賽,比賽排名前 \(\dfrac{n}{2}\) 的隊伍將會進入下一輪的淘汰賽。比賽將會打 \(\dfrac{n(n-1)}{2}\) 場,勝者得 \(3\) 分,負者得 \(0\) 分,平局雙方各得 \(1\) 分。排行榜上首先會按球隊的積分從大到小排序,如果積分相同將會比較淨勝球數(勝場比另一方領先的球數的總和減去負場比另一方落後的球數的總和的值),如果淨勝球數相同會比較進球數,如果進球數還相同則會比較字典序。試求出能夠晉級淘汰賽的 \(\dfrac{n}{2}\) 個隊伍。

資料範圍:\(1\leqslant n\leqslant 50\)

,球隊名不超過 \(30\) 個字元,單場雙方的進球數都不會超過 \(100\)。另根據 CF 官網給出的資料可得,\(n\) 保證是偶數。

Solution

看啥做啥的模擬題。

我們可以通過 \(\texttt{map}\) 直接對映得到球隊名所屬的球隊的積分、勝場比另一方領先的球數的總和、負場比另一方落後的球數的總和、進球數。然後按照如上的關鍵字次序排序,便可以得到前 \(\dfrac{n}{2}\) 名的球隊。

Code

int n;
string s[57], win[57];
map<string, int> q, goal, wingoal, losegoal;
struct team {
	string name;
	int score, wingoals, goals;
	bool operator < (const team& dxy) const {
		if(score != dxy.score)	return score > dxy.score;
		else if(wingoals != dxy.wingoals)	return wingoals > dxy.wingoals;
		else if(goals != dxy.goals)	return goals > dxy.goals;
		return name < dxy.name;
	}
}teams[57];

int main() {
	getint(n);
	_for(i, 1, n)	cin >> s[i];
	_for(i, 1, n * (n - 1) / 2) {
		string a, team1 = "", team2 = ""; int x, y;
		cin >> a; scanf("%d:%d", &x, &y);
		int len = a.size(), flag = 1;
		_for(j, 0, len - 1) {
			if(a[j] == '-')	flag++;
			else if(flag == 1)	team1 += a[j];
			else if(flag == 2)	team2 += a[j];
		}
		goal[team1] += x, goal[team2] += y;
		if(x > y)	q[team1] += 3, wingoal[team1] += (x - y), losegoal[team2] += (x - y);
		else if(x == y)	q[team1] += 1, q[team2] += 1;
		else	q[team2] += 3, wingoal[team2] += (y - x), losegoal[team1] += (y - x);
	}
	_for(i, 1, n)
		teams[i] = (team){s[i], q[s[i]], wingoal[s[i]] - losegoal[s[i]], goal[s[i]]};
	sort(teams + 1, teams + n + 1);
	_for(i, 1, n / 2)	win[i] = teams[i].name;
	sort(win + 1, win + n / 2 + 1);
	_for(i, 1, n / 2)	cout << win[i] << endl;
	return 0;
}