백준 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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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
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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
1 1 0 0
1 1 0 0
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)

통과된 코드

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#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;
}
#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; }
#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;
}

댓글 달기

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