Skip to content

Commit 2fbd6e5

Browse files
authored
명환 숙제 (#64)
1 parent 765319d commit 2fbd6e5

File tree

3 files changed

+164
-8
lines changed

3 files changed

+164
-8
lines changed

mhkim/baekjoon/1600.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* @file 1600.cpp
3+
* @brief 말이 되고픈 원숭이
4+
* @author Sam Kim (samkim2626@gmail.com)
5+
*
6+
* BFS
7+
* DFS로 풀면 최소한의 동작을 구할 수 없음
8+
* DP로도 풀 수 있을 것 같다는 생각? -> 시작점에서 도착점이 왼쪽위에서 오른쪽아래로 정해져있기 때문에?
9+
*
10+
* 말의 움직임 k번만. 어떻게 k번을 움직이는게 좋을까?
11+
* 1. 처음 풀이에는 먼저 말처럼 움직이는 것 진행 -> 이 경우 말로 이동하여 도착할 수 있는 경우 안됨
12+
* 2. 그러면 매 스텝에서 말의 움직임의 횟수를 고려하는 경로를 설정해보자 -> visited에 (말 이동한 횟수) 차원 추가
13+
*
14+
* 추가) x, y - w, h 그래프 입력받을 때 주의할 것
15+
*/
16+
#include <iostream>
17+
#include <tuple>
18+
#include <queue>
19+
20+
using namespace std;
21+
22+
int k, w, h;
23+
int g[200][200];
24+
bool visited[200][200][31];
25+
pair<int, int> horse[8] = {{1, -2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}};
26+
pair<int, int> monkey[4] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
27+
28+
int bfs(int startX, int startY)
29+
{
30+
int step = 0;
31+
int nHorse = 0; // 말처럼 이동한 횟수
32+
queue<tuple<int, int, int, int>> q;
33+
q.push(make_tuple(startX, startY, step, nHorse));
34+
visited[startX][startY][nHorse] = true;
35+
36+
while (!q.empty())
37+
{
38+
tuple<int, int, int, int> t = q.front();
39+
int x = get<0>(t);
40+
int y = get<1>(t);
41+
step = get<2>(t);
42+
nHorse = get<3>(t);
43+
q.pop();
44+
45+
if (x == w - 1 && y == h - 1)
46+
{
47+
return step;
48+
}
49+
50+
int newX, newY;
51+
// 말처럼 이동
52+
if (nHorse < k)
53+
{
54+
for (int i = 0; i < 8; i++)
55+
{
56+
newX = x + horse[i].first;
57+
newY = y + horse[i].second;
58+
if (!visited[newX][newY][nHorse + 1] && newX >= 0 && newX < w && newY >= 0 && newY < h && g[newX][newY] != 1)
59+
{
60+
visited[newX][newY][nHorse + 1] = true;
61+
q.push(make_tuple(newX, newY, step + 1, nHorse + 1));
62+
}
63+
}
64+
}
65+
66+
// 원숭이 이동
67+
for (int i = 0; i < 4; i++)
68+
{
69+
newX = x + monkey[i].first;
70+
newY = y + monkey[i].second;
71+
if (!visited[newX][newY][nHorse] && newX >= 0 && newX < w && newY >= 0 && newY < h && g[newX][newY] != 1)
72+
{
73+
visited[newX][newY][nHorse] = true;
74+
q.push(make_tuple(newX, newY, step + 1, nHorse));
75+
}
76+
}
77+
}
78+
79+
return -1;
80+
}
81+
82+
int main()
83+
{
84+
ios_base::sync_with_stdio(false);
85+
cin.tie(nullptr);
86+
87+
cin >> k >> w >> h;
88+
for (int i = 0; i < h; i++)
89+
{
90+
for (int j = 0; j < w; j++)
91+
{
92+
cin >> g[j][i];
93+
}
94+
}
95+
96+
cout << bfs(0, 0) << '\n';
97+
98+
return 0;
99+
}

mhkim/baekjoon/2437.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @file 2437.cpp
3+
* @brief 저울
4+
* @author Sam Kim (samkim2626@gmail.com)
5+
*
6+
* Greedy
7+
* 아이디어
8+
*
9+
* 만들 수 없는 최소의 양수 구하기 - 작은 추를 먼저, 잴 수 없는 무게 찾기
10+
* n번째 원소까지의 누적합 / n번째 원소
11+
* 올리려는 추가 누적합+1 보다 더 크다면, 누적합+1이 측정할 수 없는 최솟값 (추를 쌓아서 누적합 이하의 수를 모두 만들 수 있다는 것이 보장됨)
12+
*/
13+
#include <iostream>
14+
#include <algorithm>
15+
16+
using namespace std;
17+
18+
int choo[1000];
19+
20+
int main()
21+
{
22+
ios_base::sync_with_stdio(false);
23+
cin.tie(nullptr);
24+
25+
int n;
26+
cin >> n;
27+
for (int i = 0; i < n; i++)
28+
{
29+
cin >> choo[i];
30+
}
31+
sort(choo, choo + n);
32+
33+
int sum = 0;
34+
for (int i = 0; i < n; i++)
35+
{
36+
if (sum + 1 < choo[i])
37+
{
38+
break;
39+
}
40+
sum += choo[i];
41+
}
42+
43+
cout << sum + 1 << '\n';
44+
45+
return 0;
46+
}

mhkim/greedy-6.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,45 @@ int solution(vector<int> food_times, long long k)
2222
int answer = 0;
2323

2424
long long sum = accumulate(food_times.begin(), food_times.end(), 0LL);
25-
if (sum < k)
25+
if (sum <= k)
2626
{
2727
return -1;
2828
}
2929

30-
// 정렬 전 time과 index를 저장
30+
// 우선순위 큐로 time과 index를 저장: 시간이 가장 적게 걸리는 음식 순
3131
priority_queue<pair<int, int>> tni;
3232
for (int i = 0; i < food_times.size(); i++)
3333
{
3434
tni.push(make_pair(-food_times[i], i + 1)); // 파이썬은 +
3535
}
3636

3737
int nFoods = food_times.size(); // 남은 음식의 개수
38-
int sumTime = 0; // 먹는데 걸린 총 시간
38+
int prev = 0; // 이전 음식 개수
3939
while (1)
4040
{
4141
pair<int, int> top = tni.top();
42-
43-
if (sumTime + (-top.first) * nFoods > k)
42+
if ((-top.first - prev) * nFoods > k) // 더 이상 돌지 못하는 경우
4443
{
45-
answer = (k - sumTime) % nFoods break;
44+
break;
4645
}
47-
48-
sumTime += (-top.first) * nFoods;
46+
k -= (-top.first - prev) * nFoods;
47+
prev = -top.first;
4948
tni.pop();
5049
nFoods--;
5150
}
5251

52+
// 존재하는 음식 인덱스 정렬
53+
vector<int> remains;
54+
while (!tni.empty())
55+
{
56+
int idx = tni.top().second;
57+
remains.push_back(idx);
58+
tni.pop();
59+
}
60+
sort(remains.begin(), remains.end());
61+
62+
answer = remains[int(k % remains.size())];
63+
5364
return answer;
5465
}
5566

0 commit comments

Comments
 (0)