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

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <array>
using namespace std;
//총 이닝 수
int N;
// 각 이닝에 #번 선수의 결과 (편의상 0회부터, 0번 선수부터 시작으로 생각)
int player_result[51][10];
// 타순 전달받아 점수 return하는 함수
int scorePredict(vector<int>& lineup);
//안타, 2루타, 3루타, 홈런
pair<array<int, 3>, int> singleHit(array<int, 3> base_situation, int score);
pair<array<int, 3>, int> doubleHit(array<int, 3> base_situation, int score);
pair<array<int, 3>, int> tripleHit(array<int, 3> base_situation, int score);
pair<array<int, 3>, int> homerunHit(array<int, 3> base_situation, int score);
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int score, max_score = -1;
vector<int> lineup = {0, 1, 2, 3, 4, 5, 6, 7, 8}; // 0번 선수 ~ 8번 선수
cin >> N;
for(int i = 0; i < N; i++){
for(int j = 0; j < 9; j++){
cin >> player_result[i][j];
}
}
do{
// 4번타자는 무조건 0번 선수여야만 함
if(lineup[3] != 0) continue;
score = scorePredict(lineup);
if(score > max_score) max_score = score;
} while(next_permutation(lineup.begin(), lineup.end()));
cout << max_score;
return 0;
}
int scorePredict(vector<int>& lineup){
int score = 0;
int out_count = 0;
array<int, 3> base_situation = {0, 0, 0}; // 1루, 2루, 3루
int inning = 0; // 현재 몇 회인지지, 편의상 시작을 0회로
pair<array<int, 3>, int> tmpresult; // basesituation과 score 받는 tmp variable
while(1){
for(int hitter : lineup){
switch(player_result[inning][hitter]){
//0-아웃, 1-안타, ..., 4-홈런
case 0:
out_count++;
if(out_count == 3){
base_situation[0] = 0;
base_situation[1] = 0;
base_situation[2] = 0;
inning += 1;
out_count = 0;
//이닝을 더했을 때 N이면 경기 종료
if(inning == N) return score;
}
break;
case 1:
tmpresult = singleHit(base_situation, score);
base_situation = tmpresult.first;
score = tmpresult.second;
break;
case 2:
tmpresult = doubleHit(base_situation, score);
base_situation = tmpresult.first;
score = tmpresult.second;
break;
case 3:
tmpresult = tripleHit(base_situation, score);
base_situation = tmpresult.first;
score = tmpresult.second;
break;
case 4:
tmpresult = homerunHit(base_situation, score);
base_situation = tmpresult.first;
score = tmpresult.second;
break;
default:
cout << "BIG PROBLEM!" << '\n';
break;
}
}
}
}
pair<array<int, 3>, int> singleHit(array<int, 3> base_situation, int score){
if(base_situation[2] == 1){
base_situation[2] = 0;
score++;
}
if(base_situation[1] == 1){
base_situation[1] = 0;
base_situation[2] = 1;
}
if(base_situation[0] == 1){
base_situation[1] = 1;
}
base_situation[0] = 1;
return make_pair(base_situation, score);
}
pair<array<int, 3>, int> doubleHit(array<int, 3> base_situation, int score){
if(base_situation[2] == 1){
base_situation[2] = 0;
score++;
}
if(base_situation[1] == 1){
score++;
}
if(base_situation[0] == 1){
base_situation[0] = 0;
base_situation[2] = 1;
}
base_situation[1] = 1;
return make_pair(base_situation, score);
}
pair<array<int, 3>, int> tripleHit(array<int, 3> base_situation, int score){
if(base_situation[2] == 1){
score++;
}
if(base_situation[1] == 1){
base_situation[1] = 0;
score++;
}
if(base_situation[0] == 1){
base_situation[0] = 0;
score++;
}
base_situation[2] = 1;
return make_pair(base_situation, score);
}
pair<array<int, 3>, int> homerunHit(array<int, 3> base_situation, int score){
for(int i = 0; i < 3; i++){
if(base_situation[i] == 1){
base_situation[i] = 0;
score++;
}
}
score++;
return make_pair(base_situation, score);
}
최대 계산 횟수: 50 이닝 * (9-1)!
(1번 선수를 4번타자로 고정하고 나머지 선수에 대한 라인업의 경우의 수)
=> BruteForce!
캡슐화를 통해 코드의 가독성을 높이는 것을 목표로 했음.
main 함수에서 타순을 만들면, 타순을 입력받아 그 타순이 내는 점수를 return하는 함수(scorePredict)를 만드는 틀을 생각함. 모든 타순에 대해 실행한 후, 최대 스코어를 답으로 출력.