inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트

4-B

안녕하세요. 4-B 질문 있습니다.

351

kei jay

작성한 질문수 13

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

안녕하세요 큰돌님 강의 잘듣고 있습니다.

해당문제 관련해서 질문이 있는데요.

일단 비트마스킹을 이용한 풀이법은 숙지했습니다.

근데 비트마스킹을 안쓰고 풀었을때 처음에 틀렸었는데 제가 아래 올린코드에서 Reverse함수의 기저사례 단락에서 "--->이부분!" 이라고 주석표시한 부분 관련해서 궁금한게 있습니다.

문제에서 동전의 뒤집기 갯수가 2보다 작을수는 없다고 해서, 전 처음에 이게 문제가 답에대한 제한조건을 걸었다고 생각해서 저렇게 2보다 큰 경우에만 min값을 갱신하도록 코드를 짰었는데요.

저 부분을 없애야 정답이더라구요.

큰돌님 풀이에서도 2에 대한 제한조건을 거는 부분은 없는것 같은데, 문제에서 해당 예제에관한 설명이 답의 범위에 대해서 제한을 걸어놓은게 아니라 그냥 " 뒷면갯수가 2보다 작은게 불가능하다" 라고 설명해주는 부분인데 제가 잘못이해한건가요??

#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <mutex>
#include <limits.h>

using namespace std;

int n;
int coin[21][21];
int minVal=INT_MAX;

void Change(int i, int j) //요소 하나 바꾸기
{
	if (coin[i][j] == 1)
		coin[i][j]= 0;
	else
		coin[i][j]= 1;
}
void ChangeAll(int length, char hw ,int fix) // 한줄 바꾸기('h' : 행 고정 / 'w' : 열 고정)
{
	if (hw == 'h') 
		for (int i = 0; i < length; ++i)
			Change(fix, i);

	if (hw == 'w') 
		for (int i = 0; i < length; ++i)
			Change(i, fix);

}

void Reverse(int length, char fix, int fixPos) // 행 다 모든 경우의수로 다 뒤집고 열 하나씩 뒤집어보기
{

	if (fixPos == length) {
		int ret = 0;
		for (int i = 0; i < length; ++i) {
			int sum = 0;
			for (int j = 0; j < length; ++j){
				sum += coin[j][i];
			}
			if ((length - sum) > sum) 
				ret += sum;
			else
				ret += (length - sum);
		}
		if(ret>=2)  //------------------> 이부분!
			minVal = min(minVal, ret);
		return;
	}

	if (fix == 'h'){
		for (int i = 0; i < 2; ++i){
			ChangeAll(length, fix, fixPos);
			Reverse(length, fix, fixPos + 1);
		}
	}
	if (fix == 'w') {
		for (int i = 0; i < 2; ++i){
			ChangeAll(length, fix, fixPos);
			Reverse(length, fix, fixPos + 1);
		}
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> n;
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;
		for (int j = 0; j < n; ++j) {
			if (s[j] == 'H')
				coin[i][j] = 'H' - 'H' + 1;
			else
				coin[i][j] = 'T' - 'T';
		}

	}

	Reverse(n, 'h', 0);
	cout << minVal << '\n';

}

 

c++ 코딩-테스트

답변 1

0

큰돌

안녕하세요 KEI님 ㅎㅎ

혹시

문제에서 동전의 뒤집기 갯수가 2보다 작을수는 없다고 해서, 전 처음에 이게 문제가 답에대한 제한조건을 걸었다고 생각해서 저렇게 2보다 큰 경우에만 min값을 갱신하도록 코드를 짰었는데요.

이부분이요. 왜 2보다 작을수는 없다고 생각하시나요?

제 코드를 기반으로 설명하면

		int sum = 0; 
		for(int i = 1; i <= (1 << (n - 1)); i *= 2){
			int cnt = 0; 
			for(int j = 1; j <= n; j++) if(a[j] & i)cnt++;
			sum += min(cnt, n - cnt); 
		}

이런건데 이상적으로 다 뒤집어져있다면 뒤가 0인 경우의 수도 생기지 않을까요??

 

감사합니다.

0

kei jay

"<그림 3>의 상태에서 뒷면이 위를 향하여 놓인 동전의 개수는 두 개이다. <그림 1>의 상태에서 이와 같이 한 행 또는 한 열에 놓인 N개의 동전을 모두 뒤집는 작업을 계속 수행할 때 뒷면이 위를 향하도록 놓인 동전의 개수를 2개보다 작게 만들 수는 없다."

문제 지문중 일부분인데, 지금 다시 보니까 당연히 해당 예제에 국한해서 하는말인데 정신없이 읽다보니까 착각했네요

코딩살구클럽 관련 건의사항

0

4

0

코살에 19942 다이어트 문제에 N의 범위가 빠져있슴니다

0

4

0

진행 방법 질문드립니다!

0

32

2

2-I) 왜 이 문제가 그래프이론 카테고리에 있는지 잘 모르겠습니다.

0

55

2

2주차 개념#12 트리 순회

0

25

2

백준사이트가 종료된다고 합니다.

0

284

2

백준 서비스 종료

9

883

1

sk 하이닉스 코테 대비

0

367

2

3-G 최댓값 질문

0

50

1

모듈러 연산 값이 10이 아닌 경우도 있지 않나요?

0

83

2

3-I 코드 질문드립니다.

0

62

2

3-N 질문 있습니다.

0

66

2

학습방법

0

102

2

4-H 질문 있습니다 (코드 리뷰)

0

66

2

코딩테스트 어디까지 준비해야 하는지 질문이 있습니다.

0

169

2

2-O 반례가 무엇일지 어떤 부분이 틀렸는지 잘 모르겠습니다.

0

69

2

2주차 개념 #4-2. 인접행렬 질문있습니다.

0

64

2

1-A 문제풀이 후 궁금한 점이 생겨서 질문드립니다.

0

51

2

조합 재귀 풀이 확인 해주시면 감사하겠습니다.

0

68

2

함수별 시간복잡도

0

73

2

3-h 질문입니다.

0

49

1

안녕하세요 선생님. 시간 복잡도 4번 질문있습니다.

0

53

2

1-I 문제 질문 드립니다.

0

76

2

2-P 질문입니다.

0

56

1