어흥

[백준 7682] 틱택토 (C++) 본문

알고리즘/백준

[백준 7682] 틱택토 (C++)

라이언납시오 2020. 4. 16. 10:02
728x90
반응형

문제 링크: https://www.acmicpc.net/problem/7682

 

7682번: 틱택토

문제 틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임이다. 게임판은 3×3 격자판이며, 처음에는 비어 있다. 두 사람은 각각 X 또는 O 말을 번갈아가며 놓는데, 반드시 첫 번째 사람이 X를 놓고 두 번째 사람이 O를 놓는다. 어느 때든지 한 사람의 말이 가로, 세로, 대각선 방향으로 3칸을 잇는 데 성공하면 게임은 즉시 끝난다. 게임판이 가득 차도 게임은 끝난다. 게임판의 상태가 주어지면, 그 상태가 틱택토 게임에서 발생할 수 있는 최종 상태인

www.acmicpc.net

1. 주의할 점

- 만들어질 수 있는 O,X의 개수인가 (ex. O 2개, X 7개)

- 도중에 끝나는 경우, 반드시 한가지 문자만 연속된 3개를 가져야 한다

- 특수 케이스 : XOOXOOXXX -> 마지막에 2개의 연속된 3개의 X가 만들어질 수 있다 -> Valid 처리

 

2. 구현

아래 4개의 조건을 확인한다

- O,X,.의 개수를 각각 구한다

- .가 없다면. 아래의 조건을 만족 안하면 Avail = False

1) X가 O보다 개수가 1개가 많은지 확인한다. 아니라면

2) 3개의 연속된 O가 있다면

 

- .가 짝수개 && 0이 아니라면 -> X가 이겨야 한다. 아래의 조건을 만족 안하면 Avail = False

1) X가 O보다 개수가 1개 많은지 확인한다

2) 연속된 3개의 X가 1개 있는지 확인한다

3) 연속된 3개의 O가 0개 인지 확인한다

 

- .가 홀개 -> O가 이겨야 한다. 아래의 조건을 만족 안하면 Avail = False

1) O와 X의 개수가 같은지 확인한다

2) 연속된 3개의 O가 1개 있는지 확인한다

3) 연속된 3개의 X가 0개 인지 확인한다

 

#include <iostream>
#include <string>
using namespace std;
bool avail;
char arr[3][3];
int x,o,remain;		//.의 개수

int check(char c) {
	int cnt = 0;
	for (int i = 0; i < 3; i++) {
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]) {		//가로 3개 확인
			if (arr[i][0] == c) 	cnt++;	
		}
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i]) {		//세로 3개 확인
			if (arr[0][i] == c) 	cnt++;
		}
	}
	//대각선 2개 확인
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2]) {
		if (arr[1][1] == c)		cnt++;
	}
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0]) {
		if (arr[1][1] == c) 	cnt++;
	}
	return cnt;
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	string str;
	while (1) {
		cin >> str;
		if (str == "end") break;
		avail = true;
		remain = 0;	x = 0;	o = 0;
		int cnt = 0;
		for (int i = 0; i < 3; i++)
			for (int j = 0; j < 3; j++) {
				arr[i][j] = str[cnt++];
				if (arr[i][j] == '.') remain++;
				else if (arr[i][j] == 'X') x++;
				else if (arr[i][j] == 'O') o++;
			}
		//0,X,.개수 확인
		if (remain == 0) {			//맨 마지막수까지 둔 경우, 'O'3개가 연속되면 안된다
			if (x - 1 != o)		avail = false;		//개수 비교
			int result = check('O');
			if (result > 0) avail = false;			
		}
		else if (remain % 2 == 0 && remain!=0) {		//X가 O보다 1개 더 많아야 하며 X가 이겨야 한다
			if (x - 1 != o)		avail = false;		//개수 비교
			int result = check('O');
			if (result > 0) avail = false;
			result = check('X');
			if (result == 0) avail = false;
		}
		else {			//X와 O의 개수가 같아야 하며 O가 이겨야 한다
			if (x != o)		avail = false;			//개수 비교
			int result = check('X');
			if (result > 0) avail = false;
			result = check('O');
			if (result == 0) avail = false;
		}
		if (avail) cout << "valid\n";
		else cout << "invalid\n";
	}
	system("pause");
	return 0;
}
728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 1799] 비숍 (C++)  (0) 2020.04.18
[백준 16973] 직사각형 탈출 (C++)  (0) 2020.04.17
[백준 1944] 복제 로봇 (C++)  (0) 2020.04.15
[백준 1504] 특정한 최단 경로 (C++)  (0) 2020.04.14
[백준 1701] Cubeditor (C++)  (0) 2020.04.12
Comments