시간 제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 256 MB | 1324 | 295 | 227 | 29.028% |
심심했던 무지와 콘은 TV를 보다가, 대한민국 선수단이 실시간으로 출전하고 있는 경기를 보게 되었다.
지금 보고 있는 경기는 조별리그가 진행 중인데, 대한민국이 속한 조는 총 4개 국가가 참가하여 경기가 진행되고 있다.
조별리그의 규칙은 다음과 같다.
전문가들은 조별 리그의 6경기 전체에 대해서 어떤 팀이 승리할 확률, 비길 확률, 패배할 확률을 예측하였다. 무지와 콘은 모든 경기가 독립적으로 진행되었을 때 (어떠한 경기의 결과가 다른 경기의 결과에 영향을 주지 않음), 전문가들의 예상대로 진행된다면 각 팀이 조별리그를 통과하여 다음 라운드로 진출할 확률이 궁금해졌다. 하지만 무지와 콘은 직접 확률을 계산하지 못했고, 여러분들에게 도움을 요청하였다. 무지와 콘을 도와 이 문제를 해결해보자!
첫 번째 줄에 조별리그를 진행할 국가명 네 개가 공백으로 구분되어 주어진다. 주어지는 모든 국가명은 알파벳 대문자로만 구성된 길이가 1 이상 10 이하인 문자열이다.
두 번째 줄부터 일곱 번째 줄까지는 A B W D L 순으로 주어지는데, 전문가들의 예측에 따르면 A와 B가 경기를 진행했을 때 A가 승리할 확률은 W, 비길 확률은 D, 질 확률은 L이라는 의미이다.
A, B는 각각 첫 번째 줄에 있는 국가명 중 하나이고, A와 B가 같은 경우는 주어지지 않는다. 또한 W, D, L은 최대 소수점 세 자리까지 주어지며, W + D + L = 1이 보장된다.
i 번째 줄에, i 번째로 입력받은 국가가 다음 라운드에 진출할 확률을 출력한다.
출력한 결과와 실제 답을 비교하였을 때의 상대 오차 또는 절대 오차가 10^-6 이하인 경우에만 정답으로 인정한다.
경기가 이루어질 경우의 수는 3^6 = 729가지로, 그냥 브루트 포스로 구하면 될 것이라 생각했다.
다만.. 구현하기가 상당히 귀찮은 문제임을 보자마자 알 수 있었다.
미루고 미루다가 결국 풀었다.
팀 이름을 인덱스로 가져가기 위해서, hashing이란 map을 만들어 관리해주었다.
그리고 Match란 구조체를 만들어서, 6개의 경기에 각 정보를 담아주었다.
DFS로 각 경기마다 확률과 승점을 담아서 6번째 인덱스에 도착하면 계산을 치뤄주었다.
고려해야되는 경우는 크게 5가지인데, if와 else if 문으로 처리해서 가능했다.
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define FUP(i, a, b) for(int i = a; i <= b; i++)
#define FDOWN(i, a, b) for(int i = a; i >= b; i--)
#define MS(a, b) memset(a, b, sizeof(a))
#define ALL(v) v.begin(), v.end()
#define CIN(a) cin >> a;
#define CIN2(a, b) cin >> a >> b
#define CIN3(a, b, c) cin >> a >> b >> c
#define COUT(a) cout << a
#define COUT2(a, b) cout << a << ' ' << b
#define COUT3(a, b, c) cout << a << ' ' << b << ' ' << c
#define ENDL cout << '\n'
int dy[4] = { -1, 1, 0, 0 };
int dx[4] = { 0, 0, 1, -1 };
struct Match
{
string A, B;
double win, draw, lose;
friend istream& operator>>(istream&, Match& pos);
};
istream& operator>>(istream& is, Match& pos)
{
is >> pos.A >> pos.B >> pos.win >> pos.draw >> pos.lose;
return is;
}
Match match[6];
string team[4];
map<string, int> hashing;
double answer[4] = { 0, 0, 0, 0 };
void solve(double rate, vector<int> score)
{
vector<pair<int, int>> rank;
FUP(i, 0, 3)
{
rank.push_back({ score[i], i });
}
sort(ALL(rank));
if (rank[0].first == rank[3].first)
{
FUP(i, 0, 3)
{
answer[i] += (rate * 0.5);
}
}
else if (rank[1].first == rank[3].first)
{
FUP(i, 1, 3)
{
answer[rank[i].second] += (rate * 2 / 3);
}
}
else if (rank[0].first == rank[2].first)
{
answer[rank[3].second] += rate;
FUP(i, 0, 2)
{
answer[rank[i].second] += (rate / 3);
}
}
else if (rank[1].first == rank[2].first)
{
answer[rank[3].second] += rate;
FUP(i, 1, 2)
{
answer[rank[i].second] += (rate / 2);
}
}
else
{
FUP(i, 2, 3)
{
answer[rank[i].second] += rate;
}
}
}
void DFS(int idx, double rate, vector<int> score)
{
if (idx == 6)
{
solve(rate, score);
return;
}
score[hashing[match[idx].A]] += 3;
DFS(idx + 1, rate * match[idx].win, score);
score[hashing[match[idx].A]] -= 3;
score[hashing[match[idx].B]] += 3;
DFS(idx + 1, rate * match[idx].lose, score);
score[hashing[match[idx].B]] -= 3;
score[hashing[match[idx].A]]++;
score[hashing[match[idx].B]]++;
DFS(idx + 1, rate * match[idx].draw, score);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
FUP(i, 0, 3)
{
CIN(team[i]);
hashing[team[i]] = i;
}
FUP(i, 0, 5)
{
CIN(match[i]);
}
DFS(0, 1.0, { 0, 0, 0, 0 });
COUT(fixed);
cout.precision(8);
FUP(i, 0, 3)
{
COUT(answer[i]);
ENDL;
}
return 0;
}