일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 효묘블로그
- 자바
- acmicpc.net
- 파이썬강의
- 비용함수
- 머신러닝공부
- 백준 알고리즘
- 딥러닝공부
- C언어
- 비지도학습
- 딥러닝
- 머신러닝 강의
- Python강의
- 지도학습
- 파이썬강좌
- 경사하강법
- java
- Gradient Descent
- unsupervised learning
- c언어 오목
- JAVA강좌
- feature scaling
- 머신러닝 강좌
- 자바강좌
- 자바시작하기
- python강좌
- 인공지능
- 머신러닝
- supervised learning
- 선형회귀
Archives
- Today
- Total
컴공과컴맹효묘의블로그
카카오 코드 페스티벌 2018 본선 문제 풀이 - 뒤집기 본문
반응형
제출자: 61
정답자: 60
정답률: 98.4%
문제: https://www.acmicpc.net/problem/15999
풀이
문제를 조금만 관찰하면 금방 패턴을 파악할 수 있는 문제입니다.
현재 상태가 주어졌을 때 초기 상태로 가능한 경우를 생각해보면 바로 풀리는 문제입니다.
예를 들어 현재 상태가 WB였을 때, 초기상태로 가능한 것은 WW, BB, WB, BW중 하나 이상일 것입니다.
WW는 WB가 될 수 없으므로 초기상태가 불가능합니다.
BB또한 WB가 될 수 없습니다.
WB는 WB에서 0번 건들면 현재 상태가 됩니다.
BW는 WB가 되려면 B를 누르거나 W를 눌러야하는데, 그렇게되면 WW혹은 BB가 됩니다. 따라서 WB가 될 수 없습니다.
결론은 서로 인접한 격자가 다른 타일이라면 초기상태와 현재상태는 같다 입니다.
그 외의 격자들은 초기상태가 어떻든 현재상태로 만들 수 있습니다.
WW는 WW, BB, WB, BW 모두 초기상태가 가능합니다. 총 4가지 경우의 수 입니다.
WWB는 WWB, BWB가 가능합니다. 총 2가지 경우의 수 입니다.
즉, 어떤 타일에 대해서 상하좌우 모두 자신과 같은 색의 타일 (혹은 벽)이라면, 그 타일은 W이든 B이든 상관이 없다는 결론이 나옵니다. 이경우를 고립 타일 이라고 정의하겠습니다.
따라서 정답은 \(2^(\hbox{고립 타일})\)입니다.
코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
#define DIV 1000000007
int N, M;
int board[2000][2000];
bool isIsolated(int r, int c) {
int delta[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
int a = 0;
for (int i = 0; i < 4; i++) {
int dr = r + delta[i][0];
int dc = c + delta[i][1];
if (dc >= 0 && dc < M && dr >= 0 && dr < N) {
if (board[r][c] == board[dr][dc])
a++;
else
return false;
}
else
a++;
}
return (a == 4) ? true : false;
}
int exp2(int n) {
if (n == 0)
return 1;
int ret = exp2(n - 1);
return (ret * 2) % DIV;
}
int solve() {
int n = 0;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (isIsolated(i, j))
n++;
return exp2(n);
}
int main() {
scanf("%d %d", &N, &M);
for (int i = 0; i < N; i++) {
char s[2001] = { 0 };
scanf("%s", s);
for (int j = 0; j < M; j++) // W = 0, B = 1
board[i][j] = s[j] == 'W' ? 0 : 1;
}
printf("%d", solve());
}
이해되지 않는 부분이 있으시면 댓글 남겨주시면 됩니다.
반응형
Comments