[SWEA] 점심 식사시간
Date:
[SWEA] 점심 식사시간
Problem URL : 점심 식사시간
# include <iostream>
# include <cstring>
# include <vector>
# include <algorithm>
using namespace std;
int n;
int peopleNum;
int answer;
int checkPeople[10][2];
struct Person {
int x;
int y;
int target;
int distance[2];
int distDiff;
Person(int _x, int _y) : x(_x), y(_y) {};
};
struct Stair {
int x;
int y;
int value;
Stair(int _x, int _y, int _value) : x(_x), y(_y), value(_value) {};
};
vector <Person> people;
vector <Stair> stairs;
int distance(Person person, Stair stair) {
int x = abs(person.x - stair.x);
int y = abs(person.y - stair.y);
return x + y;
}
bool cmp(const Person& a, const Person& b)
{
if (a.distDiff > b.distDiff) return true;
return false;
}
void dfs(int idx) {
if (idx == peopleNum) {
vector <int> stairPeople[2];
int stairLength[2];
stairLength[0] = stairs[0].value;
stairLength[1] = stairs[1].value;
for (int i = 0; i < peopleNum; i++) {
int stairNum = people[i].target;
int tmp = people[i].distance[stairNum] + stairLength[stairNum] + 1;
if (tmp > answer) {
checkPeople[i][stairNum] = 1;
return;
}
stairPeople[stairNum].push_back(tmp);
}
int size[2];
size[0] = stairPeople[0].size();
size[1] = stairPeople[1].size();
int answerTmp = 0;
for (int i = 0; i < 2; i++) {
if (size[i] > 0) {
sort(stairPeople[i].begin(), stairPeople[i].end());
if (size[i] >= 4) {
for (int j = 3; j < size[i]; j++) {
int watingTime = stairPeople[i][j - 3] + stairLength[i] - stairPeople[i][j];
if (watingTime > 0) {
stairPeople[i][j] = stairPeople[i][j] + watingTime;
}
}
}
answerTmp = answerTmp < stairPeople[i].back() ? stairPeople[i].back() : answerTmp;
if (answerTmp > answer) {
return;
}
}
}
answer = answer < answerTmp ? answer : answerTmp;
} else {
if (people[idx].distance[0] > people[idx].distance[1]) {
people[idx].target = 1;
if (!checkPeople[idx][1]) {
dfs(idx + 1);
}
people[idx].target = 0;
if (!checkPeople[idx][0]) {
dfs(idx + 1);
}
} else {
people[idx].target = 0;
if (!checkPeople[idx][0]) {
dfs(idx + 1);
}
people[idx].target = 1;
if (!checkPeople[idx][1]) {
dfs(idx + 1);
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int TC;
cin >> TC;
for (int tc = 1; tc <= TC; tc++) {
answer = 2e9;
cin >> n;
people.clear();
stairs.clear();
memset(checkPeople, 0, sizeof(checkPeople));
int tmp;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> tmp;
if (tmp == 1) {
people.push_back(Person(i, j));
} else if (tmp > 1) {
stairs.push_back(Stair(i, j, tmp));
}
}
}
peopleNum = people.size();
// people 초기화
for (int i = 0; i < peopleNum; i++) {
int distance0 = distance(people[i], stairs[0]);
int distance1 = distance(people[i], stairs[1]);
people[i].distance[0] = distance0;
people[i].distance[1] = distance1;
people[i].distDiff = abs(distance0 - distance1);
}
// distDiff가 큰것부터 처리하도록 정렬
// distDiff가 높을수록 가까운 계단이 최적해일 확률이 높다.
sort(people.begin(), people.end(), cmp);
dfs(0);
cout << "#" << tc << " " << answer << endl;
}
return 0;
}
댓글