백준 6987번 (월드컵, C++,DFS ) [BAEKJOON]

월드컵

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

시간 제한메모리 제한제출정답맞힌 사람정답 비율
1 초128 MB83252402170231.379%

문제

월드컵 조별 최종 예선에서는 6개국으로 구성된 각 조별로 동일한 조에 소속된 국가들과 한 번씩, 각 국가별로 총 5번의 경기를 치른다.

조별 리그가 끝난 후, 기자가 보내온 각 나라의 승, 무승부, 패의 수가 가능한 결과인지를 판별하려고 한다.

다음은 가능한 결과와 가능하지 않은 결과의 예이다.

네 가지의 결과가 주어질 때 각각의 결과에 대하여 가능하면 1, 불가능하면 0을 출력하는 프로그램을 작성하시오.

입력

첫째 줄부터 넷째 줄까지 각 줄마다 6개국의 결과가 나라별로 승, 무승부, 패의 순서로 빈칸을 하나 사이에 두고 18개의 숫자로 주어진다.

승, 무, 패의 수는 6보다 작거나 같은 자연수 또는 0이다.

출력

입력에서 주어진 네 가지 결과에 대하여 가능한 결과는 1, 불가능한 결과는 0을 빈칸을 하나 사이에 두고 출력한다.

예제 입력 1

5 0 0 3 0 2 2 0 3 0 0 5 4 0 1 1 0 4
4 1 0 3 0 2 4 1 0 1 1 3 0 0 5 1 1 3
5 0 0 4 0 1 2 2 1 2 0 3 1 0 4 0 0 5
5 0 0 3 1 1 2 1 2 2 0 3 0 0 5 1 0 4

예제 출력 1

1 1 0 0

출처

Olympiad > 한국정보올림피아드 > KOI 2008 > 초등부 2번

Olympiad > 한국정보올림피아드 > KOI 2008 > 중등부 1번

알고리즘 분류

처음 문제에 대한 접근을 입력 받은 예제에서 승/무/패에 대한 데이터를 가지고 해결하는 방법으로 생각하여 조건을 추가하면서 해결하려고 했다.

1시간 정도 해보다…. 내가 못하는 건지 계속 다른 결과만 나왔다.

고민하다가 알고리즘 분류에서 브루트 포스와 백트래킹이 보이길래… 아 하나하나 해서 비교해 보는 것이 좋겠구나 해서 방향을 바꾸었다.

길을 잘못 들어서 고민을 많이 한 문제

가능한 경기는 총 15경기 배열로 어느 팀과의 경기인지 표시

문제를 입력받는 부분도 처음에는 string 값으로 받아서 처리하려고 하다가

테스트 케이스는 4가지로 이미 정해져 있고 / 팀은 6팀 / 결과는 승 무 패 -> 4 / 6 / 3 배열로 처리하였다.

테스트 케이스와 비교하는 부분은 DFS로 비교하였다.

game의 수가 15번이면 테스트 케이스와 비교하여 스코어가 다른값 없이 통과하면 결과에 1을 넣어주어 나중에 출력 (기본 0)

통과된 코드

#include <iostream>

using namespace std;

// 문제의 예상 결과를 넣기
int predictedArr[4][6][3];

// 가능한 경기는 총 15경기
int gameArr1[15] = {0,0,0,0,0,1,1,1,1,2,2,2,3,3,4};
int gameArr2[15] = {1,2,3,4,5,2,3,4,5,3,4,5,4,5,5};

// Win Draw Lose 결과
int scoreWDL[6][3];

// 결과를 저장해서 마지막에 출력
int result[4];


void Initalization()
{
	//결과 초기화
	for (int i = 0; i < 4; i++)
	{
		result[i] = 0;
	}

	// 예상 스코어를 받습니다.
	for (int n = 0; n < 4; n++)
	{
		for (int i = 0; i < 6; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				cin >> predictedArr[n][i][j];
			}
		}
	}
}

void CheckScoreRecursive(int gameCnt)
{
	// 만약 모든 경기가 끝났다면
	if (gameCnt == 15) {
		//비교
		for (int n = 0; n < 4; n++) {

			bool check = true;

			for (int i = 0; i < 6; i++) {
				for (int j = 0; j < 3; j++) {
					if (predictedArr[n][i][j] != scoreWDL[i][j]) {
						check = false;
						break;
					}
				}

				// 예측 결과가 가능하면 브레이크
				if (!check) break;
			}

			// 해당 결과가 가능하면 진입
			if (check) {
				result[n] = 1;
			}
		}

		return;
	}

	// 기준은 Arr1
	// 승리했을 경우
	scoreWDL[gameArr1[gameCnt]][0]++;
	scoreWDL[gameArr2[gameCnt]][2]++;
	CheckScoreRecursive(gameCnt + 1);
	scoreWDL[gameArr1[gameCnt]][0]--;
	scoreWDL[gameArr2[gameCnt]][2]--;

	// 무승부일 경우
	scoreWDL[gameArr1[gameCnt]][1]++;
	scoreWDL[gameArr2[gameCnt]][1]++;
	CheckScoreRecursive(gameCnt + 1);
	scoreWDL[gameArr1[gameCnt]][1]--;
	scoreWDL[gameArr2[gameCnt]][1]--;

	// 패배의 경우
	scoreWDL[gameArr1[gameCnt]][2]++;
	scoreWDL[gameArr2[gameCnt]][0]++;
	CheckScoreRecursive(gameCnt + 1);
	scoreWDL[gameArr1[gameCnt]][2]--;
	scoreWDL[gameArr2[gameCnt]][0]--;
}

int main()
{
	Initalization();

	// DFS로 시작 
	CheckScoreRecursive(0);

	// 결과 출력
	for (int i = 0; i < 4; i++)
	{
		cout << result[i] << " ";
	}

	return 0;
}

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤