[백준/BOJ] 백준 17281번 : ⚾

2020. 8. 7. 07:44알고리즘 문제풀이

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

 

17281번: ⚾

⚾는 9명으로 이루어진 두 팀이 공격과 수비를 번갈아 하는 게임이다. 하나의 이닝은 공격과 수비로 이루어져 있고, 총 N이닝 동안 게임을 진행해야 한다. 한 이닝에 3아웃이 발생하면 이닝이 종�

www.acmicpc.net

만들 수 있는 모든 라인업을 순열을 통해 만들고, 각각의 라인업이 만드는 점수중 가장 큰 점수를 구한다. 베이스의 상황은 큐를 통해 나타냈고, 이닝이 끝난 뒤 다음 이닝의 시작 선수는 startplayer를 통해 나타냈다.

 

코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

int n;
vector<vector<int>> players_result;

//player 라인업이 만드는 점수를 구한다
int makeScore(vector<int> player)
{
	int ret = 0;
	int startplayer = 0;

	//n번 이닝을 진행한다
	for (int i = 0; i < n; i++)
	{
		int out = 0;
		int score = 0;
		queue<int> base; //베이스의 상황을 큐를 통해 나타낸다

		//3아웃일때 까지 반복한다
		while (out != 3)
		{
			//이닝의 시작은 startplayer번 타자부터 시작한다
			for (int j = startplayer; j < startplayer + 9; j++)
			{
				//3 아웃일때 현재 이닝은 종료
				if (out == 3)
				{
					//다음 이닝의 시작 선수는 j번타자 이다
					startplayer = j;
					break;
				}

				//안타
				if (players_result[i][player[j % 9]] == 1)
				{
					base.push(1);
				}

				//2루타
				else if (players_result[i][player[j % 9]] == 2)
				{
					base.push(1);
					base.push(0);
				}

				//3루타
				else if (players_result[i][player[j % 9]] == 3)
				{
					base.push(1);
					base.push(0);
					base.push(0);
				}

				//홈런
				else if (players_result[i][player[j % 9]] == 4)
				{
					base.push(1);
					base.push(0);
					base.push(0);
					base.push(0);
				}

				//아웃
				else if (players_result[i][player[j % 9]] == 0)
				{
					out++;
				}

				//base의 크기가 3을 넘기면 1루,2루,3루 베이스의 표시가 넘쳤다
				//넘친부분은 score에 추가한다(사람이면 1이므로 점수가 1이 추가된다)
				while (base.size() > 3)
				{
					score += base.front();
					base.pop();
				}
			}
		}

		//해당 이닝 점수를 추가한다
		ret += score;
	}

	return ret;
}

int Solve()
{
	vector<int> player(9);
	vector<int> temp_player;

	int ret = 0;

	//0번 선수는 3번 타자 고정이므로 제외
	//그러므로 0번 선수를 제외한 1~8번 선수를 저장한다
	for (int i = 1; i < 9; i++)
	{
		temp_player.push_back(i);
	}

	do {
		//0번 선수는 3번타자 고정
		player[3] == 0;

		//1~8 수를 순열을 돌린 결과를 통해 이미 정해져 있는 3번타자를 제외한 나머지 라인업을 구한다
		for (int i = 0; i < 8; i++)
		{
			if (i >= 3) //3번타자는 고정 되어 있으므로
				player[i + 1] = temp_player[i];
			else
				player[i] = temp_player[i];
		}
		
		//각각의 라인업들이 만드는 점수중 가장 큰 점수를 구한다
		ret = max(ret, makeScore(player));

	} while (next_permutation(temp_player.begin(), temp_player.end())); //1~8의 수를 순열을 돌린다

	return ret;
}

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	int temp;

	cin >> n;

	players_result = vector<vector<int>>(n);

	//플레이어들의 이닝별 결과를 저장한다
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < 9; j++)
		{
			cin >> temp;
			players_result[i].push_back(temp);
		}
	}

	cout << Solve();

	return 0;
}