(C++) 백준 2183 - 테니스 시합

코딩너구리·2025년 10월 14일

코딩 문제 풀이

목록 보기
32/266

https://www.acmicpc.net/problem/2183

문제

> N명의 사람이 테니스 시합을 한다. 원래는 두명이 하지만 N명이 함께 플레이 한다.
> 한 시합은 여러개의 세트로 이루어지고 세트는 여러개의 게임으로 이루어진다. 각 게임은 다시 여러 턴으로 이루어진다.
> 즉, 시합을 이기려면 턴을 이기고, 게임을 이긴 뒤, 세트를 이기면 된다.
> 서브는 각 턴에 순서대로, 각 게임에선 이전 게임 첫 서브 다음 사람부터, 각 세트는 첫 세트의 첫 게임의 첫 턴에 했던 다음 사람부터 한다.
> 모두 0점에서 시작하고 점수 변화 및 승자규칙은 아래와 같다. 우선순위는 1-2-3-4이다.
> 한 세트의 승자는 최소 6게임을 이겼으며 다른 선수보다 최소 두 게임을 더 이긴 선수가 된다.
> 시합의 승자는 최소 3세트를 이긴 선수가 된다.
> 단 어떤 세트에서 한 선수가 모든 게임을 이긴 경우 두 세트를 이긴걸로 친다. 최후의 승자를 출력해라.

승자규칙

  1. 만약 x의 현재 점수가 3점이고 다른 선수들이 모두 2점을 넘지 못했으면 x가 그 게임을 이기게 된다.
  2. 만약 x의 현재 점수가 4점이면 x가 그 게임을 이기게 된다.
  3. 만약 x가 아닌 선수의 현재 점수가 4점이면 그 선수는 1점을 잃게 된다.
  4. 위의 경우가 아닌 경우 x가 단순히 1점을 얻게 된다.

접근

문제에 주어진 승자규칙에 따라 게임을 만들고
게임을 하는 반복문은 서브규칙에 따라 반복문을 만든다. 승자를 결정하는 조건을 통해 승자규칙에서 얻는 점수를 기반으로 승자를 출력한다.

문제해결

> 문제에 주어진 각 게임의 승리 조건은 사실상 필요가 없고 마지막에 세트 승자에 대한 조건을 봐야한다.
> 이를 기반으로 6승이상 완승시 2승점 획득, 다른 플레이어 보다 2게임 이상차이로 승리 시 1점 획득을 알고리즘으로 해결한다.

코드

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int N;
	string S;
	cin >> N >> S;
	char c = 'A';
	map<char, int> player;
	map<char, int> winner;
	int maxw = 0;
	while (N--)
	{
		player[c] = 0;
		winner[c] = 0;
		c++;
	}

	for (int i = 0; i < S.length(); i++)
	{
		player[S[i]] += 1;
		if (player[S[i]] >= 6)
		{
			bool perfect = true;
			bool win = true;
			for (auto& p : player)
			{
				if (p.first == S[i]) continue;
				if (p.second > 0) perfect = false;
				if (player[S[i]] < p.second + 2) win = false;
			}

			if (perfect)
			{
				winner[S[i]] += 2;
				for (auto& p : player) p.second = 0;

				if (winner[S[i]] >= 3)
				{
					cout << S[i] << '\n';
					return 0;
				}
			}
			else if(win)
			{
				winner[S[i]] += 1;
				for (auto& p : player) p.second = 0;

				if (winner[S[i]] >= 3)
				{
					cout << S[i] << '\n';
					return 0;
				}
			}
		}
	}
}

후기

수 많은 시도와 수 많은 고민을 했지만 계속 틀렸다고 나온다. 최후의 수단으로 지피티한테 물어봐도 맞다고한다.
질문게시판에 보니 뭔가 문제에 오류가 있는듯 하다.
진짜 너무 힘든 문제다.. 정답은 뭘까..

0개의 댓글