16936번: 나3곱2
나3곱2 게임은 정수 하나를 이용한다. 가장 먼저, 정수 x로 시작하고, 연산을 N-1번 적용한다. 적용할 수 있는 연산은 두 가지 있고, 아래와 같다. 나3: x를 3으로 나눈다. x는 3으로 나누어 떨어져야
www.acmicpc.net
3으로 나누는 것 - 3^k x A / 3 = 3^k-1 x A
즉 3으로 몇 번 나눠지냐 이걸 확인해준 후, 오름차순으로 정렬만 해주면 된다.
문제에서 항상 정답이 존재하는 경우에만 입력으로 주어지고, 애당초 수열B는 A를 섞어서 입력받는 거기 때문에, 안되는 경우는 없다.
9 - 3 - 6 - 12 - 4 - 8
#include <bits/stdc++.h>
using namespace std;
bool cmp(pair<long, long> &a, pair<long, long> &b) {
if (a.second == b.second) {
return a.first < b.first;
}
else return a.second > b.second;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int n;
cin >> n;
vector<pair<long,long>> v;
for (int i = 0; i < n; i++) {
long long x, temp;
int count=0;
cin >> x;
temp = x;
while (1) {
if (temp % 3 == 0) {
count++;
temp /= 3;
}
else break;
}
v.push_back(make_pair(x,count));
}
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < v.size(); i++) {
cout << v[i].first << " ";
}
}
백터의 사용방법을 계속 익혀나가야 겠다.
pair = 2개의 인자 즉 쌍을 입력받을 때 사용
tuple = 3개 이상의 인자를 입력받을 때 사용
백터의 sort 기본 정렬은 오름차순이다.
pair에서도 마찬가지인데, second 값을 기준으로 요리를 하고싶다면 함수를 하나 생성하여 비교해줄 수 있다.
16937번: 두 스티커
첫째 줄에 모눈종이의 크기 H, W, 둘째 줄에 스티커의 수 N이 주어진다. 다음 N개의 줄에는 스티커의 크기 Ri, Ci가 주어진다.
www.acmicpc.net
세로를 접할 때 = R1+R2<=H max(c1,c2)<=W
가로를 접할 때 = max(R1,R2)<=H C1+C2<=R
회전을 할때와 안할때도 각각 생각해주어야 한다.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int h, w, n;
cin >> h >> w >> n;
vector<int> r(n), c(n);
for (int i = 0; i < n; i++) {
cin >> r[i] >> c[i];
}
int ans = 0;
for (int i = 0; i < n; i++) {
int r1 = r[i];
int c1 = c[i];
for (int j = i + 1; j < n; j++) {
int r2 = r[j];
int c2 = c[j];
for (int rot1 = 0; rot1 < 2; rot1++) {
for (int rot2 = 0; rot2 < 2; rot2++) {
int range = (r1 * c1) + (r2 * c2);
if (r1 + r2 <= h && max(c1, c2) <= w) {
ans = max(range, ans);
}
if (max(r1, r2) <= h && c1 + c2 <= w) {
ans = max(range, ans);
}
swap(r2, c2);
}
swap(r1, c1);
}
}
}
cout << ans;
}
16938번: 캠프 준비
난이도가 10, 30인 문제를 고르거나, 20, 30인 문제를 고르면 된다.
www.acmicpc.net
yabmoons.tistory.com/272
조합 / 순열에 관하여 재귀함수로 잘 정리되어있는 블로그입니다. 참고하면 재귀에 관한 조합을 확실히 이해할 수 있다.
#include <bits/stdc++.h>
using namespace std;
int n, l, r, x,ans;
int a[16];
vector<int> v;
bool check[16];
void go(int idx,int cnt,int _sum) {
if (cnt >= 2) {
int min = 987654321;
int max = -987654321;
int sum = 0;
for (int i = 0; i < v.size(); i++) {
sum = sum + a[v[i]];
if (a[v[i]] < min) min = a[v[i]];
if (a[v[i]] > max) max = a[v[i]];
}
if (l <= sum && sum <= r && max - min >= x) ans++;
}
for (int i = idx; i < n; i++) {
if (check[i] == true) continue;
if (_sum + a[i] <= r) {
check[i] = true;
v.push_back(i);
go(i, cnt+1, _sum + a[i]);
v.pop_back();
check[i] = false;
}
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
//n=문재 개수, l<=문제 난이도합<=r, 가장어려움-가장쉬움>=x
cin >> n >> l >> r >> x;
for (int i = 0; i < n; i++) cin >> a[i];
go(0, 0, 0);
cout << ans;
}
4. 16943번 : 숫자 재배치
순열을 생각해서 문제를 해결한다.
#include <bits/stdc++.h>
using namespace std;
int ia[10];
int n,b;
bool check[10];
int go(int idx,int num) {
if (idx == n) {
return num;
}
int ans = -1;
for (int i = 0; i < n; i++) {
if (check[i] == true) continue;
if (idx == 0 && ia[i] == 0) continue;
check[i] = true;
int temp = go(idx+1, ia[i]+num*10);
if (temp < b) {
if (ans == -1 || ans < temp) {
ans = max(temp, ans);
}
}
check[i] = false;
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
string a;
cin >> a>>b;
n = a.size();
for (int i = 0; i < n; i++) {
ia[i] = a[i] - '0';
} // a를 숫자로 ia배열에 재저장
cout << go(0, 0);
}
15683번: 감시
스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감
www.acmicpc.net
이 문제는 dfs를 이용하여 단순 구현문제인데,
주의할점은 90도씩 방향을 바꿀 수 있다는 점이다.
1번 cctv는 한 방향만 신경 써주면 된다
2번 cctv는 양옆 위아래 이렇게 두 개를 신경 써야 하기 때문에
for (int i = 0; i <= 2; i += 2) {
int _y = y;
int _x = x;
while (true) {
int ny = _y + dy[(dir+i)%4];
int nx = _x + dx[(dir+i)%4];
이부분을 작성해주면 된다. i의 값에 따라 기준점에서 부터 i=0일때, 양옆 2일때 위아래의 검사를 하게 된다.
dx, dy의 값의 위치를 잘 생각하면서 넣어주는 것을 주의해야한다. 나는 반대로 넣었다가 마지막에 이해하여 제대로 넣었다.
#include <bits/stdc++.h>
using namespace std;
int n, m,ans=987654321;
int arr[10][10];
int dx[4] = { 0,1,0,-1 };
int dy[4] = { -1,0,1,0 };
vector<pair<int, int>> v;
vector<pair<int, int>> cctv(int here, int dir) {
vector<pair<int, int>> _change;
int y = v[here].first;
int x = v[here].second; //어떤 cctv 번호인지
if (arr[y][x] == 1) {
int _y = y;
int _x = x;
while (true) {
int ny = _y + dy[dir];
int nx = _x + dx[dir];
if (ny >= 0 && ny < n && nx >= 0 && nx < m && arr[ny][nx] != 6) {
if (arr[ny][nx] == 0) {
arr[ny][nx] = 8;
_change.push_back({ ny,nx });
}
_y = ny;
_x = nx;
}
else break;
}
}
else if(arr[y][x]==2) {
for (int i = 0; i <= 2; i += 2) {
int _y = y;
int _x = x;
while (true) {
int ny = _y + dy[(dir+i)%4];
int nx = _x + dx[(dir+i)%4];
if (ny >= 0 && ny < n && nx >= 0 && nx < m && arr[ny][nx] != 6) {
if (arr[ny][nx] == 0) {
arr[ny][nx] = 8;
_change.push_back({ ny,nx });
}
_y = ny;
_x = nx;
}
else break;
}
}
}
else if (arr[y][x] == 3) {
for (int i = 0; i < 2; i++) {
int _y = y;
int _x = x;
while (true) {
int ny = _y + dy[(dir + i) % 4];
int nx = _x + dx[(dir + i) % 4];
if (ny >= 0 && ny < n && nx >= 0 && nx < m && arr[ny][nx] != 6) {
if (arr[ny][nx] == 0) {
arr[ny][nx] = 8;
_change.push_back({ ny,nx });
}
_y = ny;
_x = nx;
}
else break;
}
}
}
else if (arr[y][x] == 4) {
for (int i = 0; i < 3; i++) {
int _y = y;
int _x = x;
while (true) {
int ny = _y + dy[(dir + i) % 4];
int nx = _x + dx[(dir + i) % 4];
if (ny >= 0 && ny < n && nx >= 0 && nx < m && arr[ny][nx] != 6) {
if (arr[ny][nx] == 0) {
arr[ny][nx] = 8;
_change.push_back({ ny,nx });
}
_y = ny;
_x = nx;
}
else break;
}
}
}
else if (arr[y][x] == 5) {
for (int i = 0; i < 4; i++) {
int _y = y;
int _x = x;
while (true) {
int ny = _y + dy[(dir + i) % 4];
int nx = _x + dx[(dir + i) % 4];
if (ny >= 0 && ny < n && nx >= 0 && nx < m && arr[ny][nx] != 6) {
if (arr[ny][nx] == 0) {
arr[ny][nx] = 8;
_change.push_back({ ny,nx });
}
_y = ny;
_x = nx;
}
else break;
}
}
}
return _change;
}
void dfs(int here) {
if (here == v.size()) {
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (arr[i][j] == 0) cnt++;
}
}
ans = min(cnt, ans);
return;
}
for (int k = 0; k < 4; k++) {
vector<pair<int, int>> _changed = cctv(here, k);
dfs(here + 1);
for (pair<int, int> b : _changed) {
arr[b.first][b.second] = 0;
}
}
return;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> arr[i][j];
if (arr[i][j] != 0 && arr[i][j] != 6) {
v.push_back(make_pair(i, j));
}
}
}
dfs(0);
cout << ans;
}
'Algorithm > 정리' 카테고리의 다른 글
[백준] 알고리즘 3-3일차 다이나믹 프로그래밍 (0) | 2021.08.09 |
---|---|
[백준] 알고리즘 3-2일차 다이나믹 프로그래밍 (0) | 2021.08.07 |
[백준] 알고리즘 3-1일차 다이나믹 프로그래밍 (0) | 2021.08.07 |
[백준] 알고리즘 3일차 다이나믹 프로그래밍 (0) | 2021.08.07 |
[백준] 알고리즘 강의 1일차 문제 및 복습 (0) | 2021.05.02 |