https://www.acmicpc.net/problem/14939
해결책
어떻게 해결합니까? 한참을 생각하다가 다른 블로그에서 글을 봤습니다.
좋은 생각으로 접근하는 방법을 찾을 수 있었고,
이것은 dfs + 비트 마스킹을 사용한 솔루션입니다.
다른 블로그에서만 솔루션을 보았으므로 솔루션이 명확하지 않을 수 있습니다.
1) 먼저 행 0에 대해 모든 2^10 경우를 시도합니다.
– 조명을 켜거나(카운트 증가) 끄거나(카운트는 동일하게 유지됨).
2) 깊이가 10일 때 i행의 조명을 끕니다(0
– i-1라인의 경우 i라인에서 불을 만질 수 있는 유일한 위치이므로 i라인에서 불을 꺼야 합니다.
– i행의 조명이 꺼진 경우 i행의 조명이 켜져 있는지 여부는 확인하지 않습니다.
(i+1 라인에서 i 라인의 조명을 끄기 때문입니다.
)
3) for 문이 끝나면 마지막 9행의 표시등을 꺼야 합니다.
– 9열에 다음 줄이 없기 때문에 전등을 끄는 장치가 없습니다.
4) 마지막 행의 조명이 모두 꺼져 있으면 카운트가 반환됩니다.
그렇지 않으면 무한대를 반환합니다.
암호
#include <iostream>
#include<vector>
using namespace std;
char arr(102)(102);
int dx(5) = { 1,0,-1,0,0 };
int dy(5) = { 0,1,0,-1,0 };
void turnSwitch(int x, int y) {
for (int i = 0; i < 5; i++) {
int tx = x + dx(i);
int ty = y + dy(i);
if (tx >= 0 && tx < 10 && ty >= 0 && ty < 10) {
arr(tx)(ty) == '#' ? arr(tx)(ty) = 'O' : arr(tx)(ty) = '#';
}
}
}
int calcTurnSwitch(int deep, int cnt) {
if (deep == 10) {
//계산
vector<pair<int, int>> pos;
for (int i = 1; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (arr(i - 1)(j) == 'O') {
turnSwitch(i, j);
cnt++;
pos.push_back({ i,j });
}
}
}
for (int i = 0; i < 10; i++) {
arr(9)(i) == 'O' ? cnt = 987654231 : cnt = cnt;
}
for (auto& p : pos) {
turnSwitch(p.first, p.second);
}
return cnt;
}
else {
int minCnt = 987654321;
minCnt = min(minCnt, calcTurnSwitch(deep + 1, cnt));
turnSwitch(0, deep);
minCnt = min(minCnt, calcTurnSwitch(deep + 1, cnt + 1));
turnSwitch(0, deep);
return minCnt;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
cin >> arr(i)(j);
}
}
cout << calcTurnSwitch(0,0) << "\n";
}