Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions 10월 5일 - 분할 정복/1244.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* [스위치 켜고 끄기] : https://www.acmicpc.net/problem/1244
*/
#include <iostream>
#include <vector>

using namespace std;

int n, m;
vector<bool> btn;

void changeMale(int num) {
for (int i = num; i <= n; i += num) { //배수
btn[i] = !btn[i]; //반대로
}
}

void changeFemale(int num) {
btn[num] = !btn[num]; //자기 자신
int size = 0;
while (true) {
size++;
if (num + size > n || num - size < 1) break; //범위 벗어나면
if (btn[num + size] != btn[num - size]) break; //같지 않으면
btn[num + size] = !btn[num + size];
btn[num - size] = !btn[num - size];
}

}

int main() {
cin >> n;
btn.assign(n + 1, false); //스위치 인덱스 : 1~n

bool val;
for (int i = 1; i <= n; i++) {
cin >> val;
btn[i] = val;
}

cin >> m;
int gender, num;
while (m--) {
cin >> gender >> num;
//입력되는 순서대로 차례대로
if (gender == 1) {
changeMale(num);
} else {
changeFemale(num);
}
}

// 20개씩 출력
for (int i = 1; i <= n; i++) {
cout << btn[i] << " ";
if (i % 20 == 0) cout << "\n";
}

}
60 changes: 60 additions & 0 deletions 10월 5일 - 분할 정복/16198.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* [에너지 모으기] : https://www.acmicpc.net/problem/16198
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
vector<int> energy;
vector<bool> visited;
int n;
int ans = -2147000000;

int computeEnergy(int x) { //구슬 x를 지웠을 때 얻을 수 있는 에너지
int lower = x - 1, upper = x + 1;
//이미 지워진 구슬은 제외시켜야 함.
while (lower > 0) {
if (visited[lower]) lower--;
else break;
}
while (upper < n - 1) {
if (visited[upper]) upper++;
else break;
}
return energy[lower] * energy[upper];
}
Comment on lines +14 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p2. 방문 체크한 값을 통해 이미 지워진 구슬은 제외하도록 풀이해주신 거 좋아요!! 그런데 구슬을 직접 '지우는' 풀이로 하면 더 간단하게 구현할 수 있어요~!! 벡터의 원소 값을 지우는 함수가 있어요! 더불어 다시 돌아왔을 때 재탐색이 가능하도록 하기 위해 삽입을 하는 함수도 알아야겠네요.


void getEnergy(int size, int sum) {
if (size == 2) { //맨 왼쪽, 맨 오른쪽 2개만 남았을 때
ans = max(sum, ans);
return;
}

//나머지 중 고르기
for (int i = 1; i < n - 1; i++) {
if (!visited[i]) {
//얻을 수 있는 에너지
int energy_mul = computeEnergy(i);
visited[i] = 1;
getEnergy(size - 1, sum + energy_mul);
visited[i] = 0;
}
}
}

int main() {
cin >> n;
energy.assign(n, 0);
visited.assign(n, 0);
for (int i = 0; i < n; i++) {
cin >> energy[i];
}

for (int i = 1; i < n - 1; i++) { //맨 처음, 맨 끝 빼고
visited[i] = 1;
getEnergy(n - 1, energy[i - 1] * energy[i + 1]); //i번째를 고름.
visited[i] = 0;
}
cout << ans << "\n";
}
93 changes: 93 additions & 0 deletions 10월 5일 - 분할 정복/17281.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* [⚾]: https://www.acmicpc.net/problem/17281
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
vector<bool> base(4); //1루, 2루, 3루

// num : 1~4 전진
int move(int num) {
int sum = 0;
for (int i = 3; i >= 1; i--) { //3루~1루순으로 전진
if (base[i] && i + num > 3) { //홈에 도착할 수 있는 경우
sum++;
base[i] = false;
continue;
}
if (base[i]) {
base[i + num] = base[i];
base[i] = false;
}
Comment on lines +15 to +23
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 움직이는 부분 함수로 만들어 주신 거 완전 좋아요!!! 사소한 코멘트인데 base[i] = false 코드가 중복되니 지금 있는 if문 2개는 공통되는 조건이 큰 if문으로 오게 하나로 합쳐도 좋겠네요~!!

}
if (num <= 3) base[num] = 1; // 홈런인 경우 빼고
return sum;
}

int computeScore(int n, vector<int> &order, vector<vector<int>> &result) {
int total_score = 0;
int idx = 1;
int cur_order = order[idx]; //1번 타자 선수부터 시작
for (int i = 0; i < n; i++) { // n이닝 동안
base.assign(4, false); // 이거 안해줌; 각 이닝마다 다시 시작...
int out = 0; //3아웃되면 종료
while (out < 3) {
switch (result[i][cur_order]) { //i번째 이닝의 cur_order 선수의 기록
case 0: //아웃
out++;
break;
case 1: //안타.
total_score += move(1);
break;
case 2: //2루타
total_score += move(2);
break;
case 3: //3루타
total_score += move(3);
break;
case 4: //홈런
total_score += move(4);
total_score++; //타자까지 득점
break;
}
idx++;
if (idx == 10) idx = 1; //인덱스는 1~9까지
cur_order = order[idx]; //다음 타자
}
}
return total_score;
}

int main() {
int n, ans = -1;
cin >> n;
vector<vector<int>> result(n, vector<int>(10, 0)); //n이닝 , 9번 타자까지 (인덱스 1~9)
vector<int> player(8); //순열을 만들기 위함
vector<int> order(10); // 결정된 타순
//input
for (int i = 0; i < n; i++) {
for (int j = 1; j <= 9; j++) {
cin >> result[i][j];
}
}
//순열 만들기용
for (int i = 0; i < 9; i++) {
player[i] = i + 2; //2~8 (1번은 이미 결정되었으니까)
}
Comment on lines +76 to +78
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p1. player의 배열 크기는 8인데 인덱스는 8까지 참조하고 있네요!

//순서 순열 만들기
do {
for (int i = 0; i < 3; i++) {
order[i + 1] = player[i];
}
order[4] = 1; // 1번타자는 4회 고정
for (int i = 3; i < 8; i++) {
order[i + 2] = player[i];
}
Comment on lines +81 to +87
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 벡터의 삽입 함수를 활용하면 더 간단하게 바꿔볼 수 있을 것 같아요!

ans = max(ans, computeScore(n, order, result));
} while (next_permutation(player.begin(), player.end()));
cout << ans << "\n";
return 0;
}

55 changes: 55 additions & 0 deletions 10월 5일 - 분할 정복/17829.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* [222-풀] : https://www.acmicpc.net/problem/17829
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<vector<int>> map;

int findSecond(int r, int c) {
vector<int> arr;
//2*2
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
arr.push_back(map[r + i][c + j]);
}
}
sort(arr.begin(), arr.end());
return arr[2]; //2번째로 큰 수
}

int pooling(int size) {
//사이즈가 1이면
if (size == 1) {
cout << map[0][0] << "\n";
//return map[0][0]; // 🖍 이걸로 하면 엄청나게 큰 수가 뜹니다...?! 왜일까요 cout으로 하면 잘 나오는데..
return 0;
}
Comment on lines +26 to +30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size가 1이어서 해당 if문에 걸리는 현재 함수는, 호출의 가장 마지막 함수예요!
그래서 return map[0][0]을 하면 바로 main에 보내주는 게 아니라 호출을 당한 전 함수로 계속 리턴해줘요!
그런데 지금 작성해주신 pooling함수는 호출 시 리턴 값을 따로 저장하거나, 다시 리턴해주는 부분이 없으니 main으로 보내주는 게 없어 쓰레기 값이 출력된 것 같습니다!!


// 2*2씩 두번째 큰 수 구하고, 배열 1/4크기 왼쪽 위에 담기
for (int i = 0; i < size; i += 2) {
for (int j = 0; j < size; j += 2) {
map[i / 2][j / 2] = findSecond(i, j);
}
}
pooling(size / 2);
return 0;
}

int main() {

int n;
cin >> n;
map.assign(n, vector<int>(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> map[i][j];
}
}

pooling(n);
return 0;
}
43 changes: 43 additions & 0 deletions 10월 5일 - 분할 정복/2447.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* [별 찍기 - 10] : https://www.acmicpc.net/problem/2447
*/
#include <iostream>
#include <vector>

using namespace std;
vector<vector<char>> map;

void makeStar(int n, int r, int c) { //n, r시작 위치, c시작 위치
if (n == 3) { // 크기 3패턴 별 찍기.
for (int i = r; i < r + 3; i++) {
for (int j = c; j < c + 3; j++) {
map[i][j] = '*';
}
}
map[r + 1][c + 1] = ' '; //가운데
return;
}
Comment on lines +11 to +19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 아래 for문에서 9등분씩 계속 분할해주는 걸 생각하면 지금 코드를 더 짧게 줄일 수 있겠네요! 하지만 3에서 끊어주신 것도 시간을 조금 더 절약할 수 있을테니 좋아요~~!!


//3보다 큰 경우
//테두리 8개 재귀 호출
for (int i = 0; i < n; i += n / 3) { // 행 시작 점
for (int j = 0; j < n; j += n / 3) { //열 시작 점
if (i == n / 3 && j == n / 3) continue; //가운데 뚫린 거 패스
makeStar(n / 3, r + i, c + j);
}
}
}

int main() {
int n;
cin >> n;
map.assign(n, vector<char>(n + 1, ' '));
makeStar(n, 0, 0);
//출력
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << map[i][j];
}
cout << "\n";
}
}