https://www.acmicpc.net/problem/1285
1285번: 동전 뒤집기
첫째 줄에 20이하의 자연수 N이 주어진다. 둘째 줄부터 N줄에 걸쳐 N개씩 동전들의 초기 상태가 주어진다. 각 줄에는 한 행에 놓인 N개의 동전의 상태가 왼쪽부터 차례대로 주어지는데, 앞면이 위
www.acmicpc.net
1. 비트마스킹 개선방법
행탐색(2^20) * 열탐색(2^20) -> 2^40 -> 터진다.
해결 : 행만바꾼후, 열은 최적해가 정해져있다. -> 열을 노가다로 탐색X
ex) HTT 가 열인경우, 뒤집으면 THH가 된다. -> 뒤집는게 최적해다!
THH가 열인경우, 안뒤집는게 최적해다!
결론 : 행만뒤집은후, t가 절반보다많으면 뒤집으면된다!
2. 전체코드
#include <bits/stdc++.h>
using namespace std;
char a[24][24],origin[24][24];
int n,ret=987645321;
void copy() {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
a[i][j] = origin[i][j];
}
}
}
void swap_hang(int r) {
for (int i = 0; i < n; ++i) {
if(a[r][i]=='T')
a[r][i] = 'H';
else if(a[r][i] == 'H')
a[r][i] = 'T';
}
}
void swap_yul(int r) {
for (int i = 0; i < n; ++i) {
if (a[i][r] == 'T')
a[i][r] = 'H';
else if (a[i][r] == 'H')
a[i][r] = 'T';
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cin >> origin[i][j];
}
}
//행,열 모두뒤집 -> 2^40 -> 터짐
//해결 : 행만뒤집 and 열은 최적해가 정해져있음!
for (int subset1 = 0; subset1 < (1 << n); ++subset1) { //행
//
copy();
for (int i = 0; i < n; ++i) {
if (subset1 & (1 << i)) {
swap_hang(i);
}
}
int cnt = 0; //전체배열에서 t의갯수(최소화해야함)
for (int i = 0; i < n; ++i) {
int t = 0; //한행에서 T의갯수
for (int j = 0; j < n; ++j) {
if (a[j][i] == 'T') t++;
}
if (t > n/2) { //뒤집으면됨
cnt += n - t;
}
else {
cnt += t;
}
}
ret = min(ret, cnt);
}
cout << ret;
return 0;
}
'Algorithm > 비트마스킹' 카테고리의 다른 글
프로그래머스 메뉴리뉴얼 c++ // 비트마스킹 조합 (0) | 2024.01.08 |
---|---|
백준 17471 게리멘더링 c++ // 비트마스킹, dfs (0) | 2023.12.21 |
백준 19942 c++ //비트마스킹, 벡터사전순 정렬방법 (0) | 2023.12.15 |
프로그래머스 양과늑대 c++ // 상태기반 dfs 방법 , 비트마스킹 (0) | 2023.12.12 |
프로그래머스 양궁대회 c++ // 비트마스킹 하는 방법, 완전탐색 (0) | 2023.12.12 |