반응형
핵심
1. beginning과 target의 xor연산으로 같은 값(1)과 다른 값(0)을 표현한 후, 이걸 모두 1로 만드는 문제로 재정의
2. 기준 줄을 가로로 설정하면(세로도 상관없음), 각 가로줄이 모두 Flip을 통해 기준 줄이 될 수 있어야 함
- 2번이 성립 안하면 목표 상태를 만들 수 없음
저는 이 두가지를 떠올려서 해결했습니다!
문제는 코드 아래에 있습니다.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#include <string>
#include <vector>
using namespace std;
/*
<문제>
동전을 행, 열 단위로 한꺼번에 뒤집어서 원하는 동전 배열 만들기
필요한 최소 뒤집기 수 구하기
동전들의 초기상태 2차원 정수배열 beginning, 목표상태인 target이 주어졌을 때
필요한 동전뒤집기 횟수 최솟값 return
목표상태를 만들지 못하는 경우 -1 return
beginning길이(=target길이) <= 10
beginning[i]길이 <= 10
beginning, target [i][j]는 각각 (i+1, j+1)의 동전 상태를 나타내며, 0은 앞면, 1은 뒷면 의미
<풀이>
beginning과 target의 차이를 먼저 파악 -> xor 연산한 결과 저장
-> 이 결과에 적절히 뒤집기 연산해서 모두 1로 만들면 되는 거
가로줄 뒤집기를 통해 각 가로줄이 모두 같아질 수 있어야 함 / 아니면 목표상태 못만드는 거
가로, 세로 어떤 걸 기준으로 해도 수는 똑같음 / 단, 가로줄에서 가능한 형태가 2가지가 나옴
-> 먼저, beginning과 target xor연산 - O(10*10)
가로줄을 뒤집어가며 하나의 형태로 만들기 - O(10*10)
형태가 다른데, 뒤집어도 같은형태가 안나오면 -1 return
모든 가로줄을 뒤집어서 같은 형태로 만들었으면
0 1을 보면서 세로줄 뒤집기 - O(10)
뒤집기 카운트 return
* 가로줄의 형태 기준이 2가지가 있음 -> 이 두가지 케이스를 모두 비교해봐야 함
<시간>
O(n^2)이나, n이 10이라 가능할 듯
*/
//각 벡터 값이 같은지(true) 다른지(false)를 반환
bool compareGaro(vector<int> standard, vector<int> xor_res){
for(int j=0; j<standard.size(); j++)
//각 요소 비교
if(standard[j]!=xor_res[j])
return false;
return true;
}
//뒤집기 연산
vector<int> Flip(vector<int> a){
for(int i=0; i<a.size(); i++)
if(a[i]==0) a[i]=1; else a[i]=0;
return a;
}
//정답 구하는 함수
int getAnswer(int garo, int sero, vector<int> standard, vector<vector<int> > xor_res, int answer){
//모든 가로줄을 뒤집어가며 동일한 형태로 바꾸기
for(int i=1; i<sero; i++){
//가로줄을 뒤집어가며 하나의 형태로 만들기
bool flag = compareGaro(standard, xor_res[i]);
//첫줄과 같지 않은 경우
if(flag==false){
//뒤집기(카운트 증가)
xor_res[i] = Flip(xor_res[i]); answer++;
//뒤집어도 첫줄과 다르면 불가능한 경우
if(compareGaro(standard, xor_res[i])==false) return -1;
}
}
//이제 세로 뒤집기 카운트하면 됨
for(int i=0; i<garo; i++)
if(standard[i]==0) answer++;
return answer;
}
int solution(vector<vector<int>> beginning, vector<vector<int>> target) {
int answer = 0;
vector<vector<int>> xor_res; //xor연산결과
//xor연산결과 생성
for(int i=0; i<target.size(); i++){
vector<int> a;
for(int j=0; j<target[0].size(); j++){
if(beginning[i][j]==target[i][j]) a.push_back(1);
else a.push_back(0);
}
xor_res.push_back(a);
}
int sero = target.size(), garo = target[0].size(); //가로세로 길이
vector<int> standard = xor_res[0]; //첫 줄이 기준
//첫 정답
answer = getAnswer(garo, sero, standard, xor_res, answer);
//가로줄 기준을 바꾸기(flip한 형태로 - answer이 1부터 시작)
standard = Flip(standard);
int another_answer = getAnswer(garo, sero, standard, xor_res, 1);
//비교 후 리턴
if(answer > another_answer) return another_answer;
return answer;
}
|
cs |
반응형
'알고리즘 문제풀이' 카테고리의 다른 글
[Programmers] 프로그래머스 Lv.1 체육복 문제풀이(C++) (2) | 2023.11.09 |
---|---|
[Programmers] 프로그래머스 Lv.1 달리기 경주 문제풀이(C++) (0) | 2023.11.09 |
[BackJoon] 백준 백설 공주와 일곱 난쟁이(3040) 문제풀이(C++) (0) | 2023.10.20 |
[BackJoon] 백준 보물(1026) 문제풀이(C++) (0) | 2023.10.20 |
[CodeForces] 코드포스 Asterisk-Minor Template 문제풀이(C++) (1) | 2023.10.19 |