백준 2503 - 숫자 야구(C언어)

컴퓨터/문제풀이집

728x90
반응형

 

 

2503번: 숫자 야구

첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트

www.acmicpc.net

문제 파악 및 구현 준비

  • 숫자 야구 게임
  • 질문의 최대 횟수 100회
  • 질문을 토대로 남아있는 정답의 경우의 수를 구하기

문제 자체의 내용은 어렵지 않았습니다. 구현 아이디어는 아래와 같습니다.

  • 총 숫자 야구게임의 경우의 수를 구해서 2차원 배열을 통해 숫자 값과 그 숫자가 가능성이 있는지 저장하기 위한 배열 지정
  • 테스트 케이스 입력 
  • 테스트 케이스의 데이터와 총 숫자 야구게임 경우의 수를 비교하며 가능성이 있는 수와 없는 수를 찾아내기
  • 최종적으로 가능성이 있는 수만 찾아내어 출력하기

전체 소스코드

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<malloc.h>

int main() {

	// 숫자 야구 경우의 수 만들기 및 저장
	int cnt = 0;
	int gameData[504][2]; // [0]에는 경우의 수 data [1]에는 0 과 1로 가능성이 있는지 판단하기
	for (int i = 1; i <= 9; i++) {
		for (int j = 1; j <= 9; j++) {
			for (int k = 1; k <= 9; k++) {
				if (i == j || i == k || j == k) {
					continue;
				}
				//printf("%d %d %d\n", i, j, k);
				gameData[cnt][0] = i * 100 + j * 10 + k;
				gameData[cnt][1] = 0;
				cnt++;
			}
		}
	}
	//printf("%d\n", cnt);

	// 테스트 케이스 입력받기
	int testCase = 0;
	scanf("%d", &testCase);
	int testData[100][3];
	for (int i = 0; i < testCase; i++) {
		scanf("%d", &testData[i][0]);
		scanf("%d", &testData[i][1]);
		scanf("%d", &testData[i][2]);
	}

	// 게임 데이터에서 스트라이크와 볼 계산
	int strike;
	int ball;
	for (int i = 0; i < testCase; i++) {
		for (int j = 0; j < cnt; j++) {

			// 입력받은 테스트 케이스를 거치면서 모든 게임 데이터와 경우의 수 확인
			// 만약 이미 계산해본 게임 데이터라면 Pass
			if (gameData[j][1] == 1) continue;
			strike = 0;
			ball = 0;

			// 3자리 숫자로 입력된 값들을 분리
			int d1 = gameData[j][0] / 100;
			int d2 = gameData[j][0] % 100 / 10 ;
			int d3 = gameData[j][0] % 10;
			int i1 = testData[i][0] / 100;
			int i2 = testData[i][0] % 100 / 10;
			int i3 = testData[i][0] % 10;

			// 테스트 케이스와 게임 경우의 수를 비교하며 스트라이크 및 볼 계산
			if (d1 == i1 ) strike++;
			if (d2 == i2)  strike++;
			if (d3 == i3)  strike++;
			if (i1 == d2 || i1 == d3) ball++;
			if (i2 == d1 || i2 == d3) ball++;
			if (i3 == d2 || i3 == d1) ball++;

			//만약 테스트 케이스의 볼과 스트라이크가 게임 데이터의 숫자와 다르다면 가능성이 없는 수
			// 따라서 1로 변경
			if (!(testData[i][1] == strike && testData[i][2] == ball)) {
				gameData[j][1] = 1;
			}
		}
	}

	// 전체 게임 데이터를 순환하며 가능성이 있는 수만을 카운팅 및 출력
	int result = 0;
	for (int i = 0; i < cnt; i++) {
		if (gameData[i][1] == 0) result++;
	}
	printf("%d\n", result);
	return 0;
}

후기 

브루트포스 알고리즘을 사용하여 푸는 문제로 다른 웹 결과에서는 스마트한 방법이 많았지만, 처음 생각한 대로 접근해서 구현했다. 

여러 기법들을 사용하면 조금 더 깔끔하게 소스가 작성되고 효율이 좋아질수는 있지만 문제의 제작 의도대로 가장 원초적인 방법으로 접근하여 문제를 풀었다.

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :