swea
SWEA::2383 점심 식사시간
software expert academy
swea::2383 점심 식사시간
시사점
- 변수 하나를 잘못 사용하여, 찾는데 정말 많은 시간을 소모하였습니다.
- 로직이 분명히 맞지만, 틀린 곳을 찾아야할땐 정말 쉽지 않습니다.
- 처음부터 변수 하나 하나 사용할때마다 주의깊게 사용해야겠습니다.
이해(6)
- 2개의 계단이 있습니다.
- 최대 10명의 사람이 있습니다.
- 각 사람은 2개의 계단 중 하나를 선택하여 내려갈 수 있습니다.
- 사람들은 원하는 계단에 최단거리로 이동한 후 1초를 대기합니다.
- 대기 후, 계단을 내려가는 중인 사람의 수가 3보다 작은 경우 합류할 수 있고,
- 그렇지 않은 경우, 누군가가 땅에 도착해야 합류할 수 있습니다.
- 계단을 내려가는 시간은 계단의 길이로 주어집니다.
- 이때, 사람들을 적절히 계단에 배분하여 모든 사람이 땅에 도달하는 최소 시간을 출력합니다.
설계, 손 코딩(5)
- 손으로 중심이 되는 코드를 구현합니다.
- 시뮬레이션 문제입니다.
- 최대 10명이므로, backtrack으로 각 사람마다 계단을 선택해줍니다.
- 이후, 시뮬레이션을 돌려줍니다.
- naive하지 않게 시간을 조절하려 하였지만, queue가 2개라 쉽지 않습니다.
복잡도
- 2^10 * simulateion
- simulation은 최악의 경우 사람 10명이 하나의 계단만 선택하고, 맵이 10 * 10 인 경우입니다.
- 따라서, waitQ에 대략 20짜리 10개가 들어있다고 생각하면 됩니다.
- 그래도 naive하게 풀어도 될만큼 수가 매우 작습니다.
구현(17)
#include<bits/stdc++.h>
#define endl '\n'
#define pb push_back
#define all(v) (v).begin(), (v).end()
#define rep(i,a,b) for(int i=a;i<b;i++)
#define r_rep(i,a,b) for(int i=a;i>b;i--)
const int MAXN = 10, inf = 0x3f3f3f3f;
typedef std::pair<int,int> pii;
using namespace std;
int n, ans;
int a[MAXN][MAXN];
vector<pii> ppl;
vector<pii> step;
vector<int> height;
priority_queue<int> waitQ, descendQ; // min
void input(){
ppl.clear();
step.clear();
height.clear();
cin >> n;
rep(i, 0, n){
rep(j, 0, n){
int x; cin >> x;
if(x == 1) ppl.pb({i, j});
else if(x > 1) step.pb({i, j}), height.pb({x});
}
}
}
int simulate(int stp, vector<int> grp){
int curT = 0;
// init
rep(i, 0, grp.size()){
int dist = abs(ppl[grp[i]].first - step[stp].first) + abs(ppl[grp[i]].second - step[stp].second);
waitQ.push({-(dist + 1)});
}
while(true){
while(!descendQ.empty()){
int endt = -descendQ.top();
if(endt <= curT) descendQ.pop();
else break;
}
while(!waitQ.empty()){
int t = - waitQ.top();
if((int) descendQ.size() < 3 && t <= curT){
descendQ.push(-(curT + height[stp])); // 실수(22m) : t가 아니라 curT
waitQ.pop();
}else break;
}
if(waitQ.empty() && descendQ.empty()) break;
curT++;
}
return curT;
}
void backtrack(int idx, vector<int> bipartate[2]){
if(idx == ppl.size()){
// simulate
ans = min(ans, max(simulate(0, bipartate[0]), simulate(1, bipartate[1])));
return;
}
bipartate[0].pb({idx});
backtrack(idx+1, bipartate);
bipartate[0].pop_back();
bipartate[1].pb({idx});
backtrack(idx+1, bipartate);
bipartate[1].pop_back();
}
void process(){
ans = inf;
input();
vector<int> bipartate[2];
backtrack(0, bipartate);
cout << ans << endl;
}
int main(){
freopen("input.txt","r",stdin);
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int tc; cin >> tc;
rep(t, 1, tc+1){
cout << "#" << t <<" ";
process();
}
return 0;
}
디버깅(22)
- (22m) : descendQ.push(-(curT + height[stp])); // 실수(22m) : t가 아니라 curT
- 계단에 도착하자마자 내려간다면 t를 사용하겠지만,
- 계단에 도착한 이후 대기하는 경우가 있으므로 curT를 사용해야 합니다.