순간을 성실히, 화려함보단 꾸준함을

[boj : 7682] 틱택토 본문

알고리즘,SQL/백준,BOJ

[boj : 7682] 틱택토

폭발토끼 2020. 12. 20. 16:20

www.acmicpc.net/problem/7682

 

7682번: 틱택토

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 줄은 9개의 문자를 포함하며, 'X', 'O', '.' 중 하나이다. '.'은 빈칸을 의미하며, 9개의 문자는 게임판에서 제일 윗 줄 왼쪽부터의 순서이다. 입

www.acmicpc.net

문제 : 틱택토가 될 수 있는 경우의 수가 주어졌을때만 valid 아니면 invalid 를 출력해라.

 

해설 :  처음에 예시랑 문제보고 뭔 멍멍이소리인가 싶었음. 알고보니 한줄씩 9문자를 차례대로 3x3 보드에 넣는 거였음

안될 조건을 찾는게 은근 까다로움,,,,

하나씩 살펴보자

 

끝낼 조건 : 가로/세로/대각선 중 하나라도 3개가 연다라 붙어있으면 끝, 아닐때 보드의 칸은 X,O로 가득 채워져야함

1) 연이은 x의 개수가 1개이고 연이은 o의 개수는 하나도 없어야 됨, 이때 보드의 x의 총 개수는 o보다 항상 1개 더 많아야 됨.=>((retx==1 && reto==0) && x==y+1)

2) 연이은 o의 개수가 1개이고 연이은 x의 개수는 하나도 없어야 됨. 이때 보드의 x의 총 개수는 항상 o와 같음

=>((retx==0 && reto==1) && x==y))

3) o,x 둘다 연이은 문자가 존재 하지 않을때, 무조건 보드의 판은 꽉 채워져 있어야 하며, 이때 항상 x=5 y=4 개 이어야 됨.=>((retx==0 && reto==0) && x==5 && y==4)

 

이를 하나씩 확인하면 되는데, 보드를 확인할 때 가로/세로/대각선 을 각각 따로 확인하고 만약 각 실행시 0이 아니라면 바로 return 시켜주자.

XOO

XXX

XO.

인 경우는 가로/세로 X가 연이은게 하나씩 존재한다. 그러나 확인할때 합쳐서 확인해 버리면 invalid를 출력해버림.

#include<bits/stdc++.h>

using namespace std;

char board[3][3];

string solve();
int draw(char ch);

int main()
{
	string s;
	while (true) {
		int h = 0, w = 0;
		cin >> s;
		if (s == "end")break;
		for (int i = 0; i < s.length(); i++) {
			board[h][w++] = s[i];
			if (w == 3)
				h++, w = 0;
		}
		cout << solve()<<"\n";
	}
	return 0;
}
string solve()
{
	int x = 0, y = 0, c = 0;
	for (int i = 0; i < 3; i++)
		for (int j = 0; j < 3; j++) {
			if (board[i][j] == '.')c++;
			else if (board[i][j] == 'X')x++;
			else y++;
		}
	int retx = draw('X');
	int reto = draw('O');

	if ((retx == 1 && reto == 0) && (x == y + 1))return "valid";
	if ((retx == 0 && reto == 1) && (x == y))return "valid";
	if ((retx == 0 && reto == 0) && x == 5 && y == 4)return "valid";
	return "invalid";
}
int draw(char ch)
{
	int cnt = 0,ret=0;
	//가로
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++)
			if (ch == board[i][j])cnt++;
		if (cnt >= 3)ret++;
		cnt = 0;
	}
	if (ret != 0)return ret;
	//세로
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++)
			if (ch == board[j][i])cnt++;
		if (cnt >= 3)ret++;
		cnt = 0;
	}
	if (ret != 0)return ret;

	//왼쪽위부터 오른쪽 아래(대각선)
	for (int i = 0; i < 3; i++)
		if (ch == board[i][i])cnt++;
	if (cnt >= 3) ret++;
	cnt = 0;
	if (ret != 0)return ret;
	//왼쪽밑부터 오른쪽 위(대각선)
	for (int i = 0; i < 3; i++)
		if (ch == board[2 - i][i])cnt++;
	if (cnt >= 3)ret++;
	return ret;
}

 

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

[boj : 1833] 고속철도 설계하기  (0) 2020.12.22
[boj : 12739] 돌림판(small)  (0) 2020.12.22
[boj : 2758] 로또  (0) 2020.12.18
[boj : 3709] 레이저빔은 어디로  (0) 2020.12.17
[boj : 19846] 신기한 연산  (0) 2020.12.16