※ 출처 : 프로그래머스>PCCP 기출 LV2. 충돌 위험 찾기
각 로봇이 routes에 정의된 지점 간의 경로를 계산하여 route에 저장
경로 계산은 다음과 같이 이루어집니다:
x축과 y축을 각각 따로 고려하여, 한 방향으로 먼저 움직인 후 다음 방향으로 움직입니다.
모든 로봇의 경로가 계산된 후, 가장 많이 움직인 로봇의 최대 경로 길이를 기준으로 각 시간마다 각 좌표에서 몇 대의 로봇이 존재하는지 카운트
동일한 좌표에 여러 로봇이 있는 경우, 즉 두 로봇 이상이 같은 위치에 있다면 answer 값 증가
#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
int dx[4] = { 1,-1,0,0 };
int dy[4] = { 0,0,1,-1 };
//! r행(위아래)로 먼저 움직이고, c열(좌우)로 움직임
// 로봇 별 이동 경로
map<int, vector<pair<int, int>>> route;
int solution(vector<vector<int>> points, vector<vector<int>> routes)
{
int answer = 0;
int x = routes.size(); // 로봇 개수
int move_cnt = routes[0].size(); // 포인트 이동 횟수
for (int i = 0;i < x;i++)
{
int n = 0;
vector<pair<int, int>> r;
for (int j = 0;j < move_cnt - 1;j++)
{
// 지점에서 다른 지점 갈때 다시 출발하면 안됨.
int before_x = points[routes[i][j] - 1][0];
int before_y = points[routes[i][j] - 1][1];
int next_x = points[routes[i][j + 1] - 1][0];
int next_y = points[routes[i][j + 1] - 1][1];
int k = before_x;
int l = before_y;
// 아래로
if (before_x < next_x)
{
if (j != 0) k++;
for (;k <= next_x;)
r.push_back({ k++,before_y });
k -= 1;
// 우로 이동
if (before_y < next_y)
{
l += 1;
for (;l <= next_y;l++)
r.push_back({ k,l });
}
// 좌로 이동
else if (before_y > next_y)
{
l -= 1;
for (;l >= next_y;l--)
r.push_back({ k,l });
}
}
// 위로
else if (before_x > next_x)
{
if (j != 0)
k--;
for (;k >= next_x;)
r.push_back({ k--,before_y });
k += 1;
// 우로 이동
if (before_y < next_y)
{
l += 1;
for (;l <= next_y;l++)
r.push_back({ k,l });
}// 좌로 이동
else if (before_y > next_y)
{
l -= 1;
for (;l >= next_y;l--)
r.push_back({ k,l });
}
}
else
{
// 우로만
if (before_y < next_y)
{
if (j != 0) l++;
for (;l <= next_y;l++)
r.push_back({ k,l });
}
else // 좌로만
{
if (j != 0) i--;
for (;l >= next_y;l--)
r.push_back({ k,l });
}
}
}
route.insert({ i + 1,r });
}
// 1,2,... n번째 로봇까지의 경로 : r (vector<pair<int,int>>)
int max_len = 0;
for (int i = 0;i < x;i++)
if (max_len < route[i + 1].size())
max_len = route[i + 1].size();
// 최대 좌표 이동 횟수
for (int k = 0;k < max_len;k++)
{
// 로봇의 수 (좌표 출현 갯수) -> second(int)의 값이>1인 경우 answer++;
map<pair<int, int>, int> loc_cnt;
for (int a = 0;a < x;a++)
if (route[a + 1].size() > k)
loc_cnt[{route[a + 1][k].first, route[a + 1][k].second}]++;
for (auto iter = loc_cnt.begin();iter != loc_cnt.end();iter++)
if (iter->second > 1) answer++;
}
return answer;
}
반복문과 조건문의 향연... ->
결론 !
이 소스는 답이 없다. 다시해라 ㅠㅠㅠㅠㅠㅠ힝....
#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
int solution(vector<vector<int>> points, vector<vector<int>> routes)
{
int answer = 0;
// x : 로봇의 수
int x = routes.size();
// move_cnt : 포인트 이동 횟수
int move_cnt = routes[0].size();
map<int, vector<pair<int, int>>> route;
// x개의 로봇이 돌아다님
for (int i = 0;i < x;i++)
{
// i+1번째 로봇의 이동 경로
vector<int> r = routes[i];
vector<pair<int, int>> rtmp;
// r : {4,2}
for (int z = 0;z < r.size() - 1;z++)
{
int before_x = points[r[z] - 1][0];
int before_y = points[r[z] - 1][1];
int next_x = points[r[z + 1] - 1][0];
int next_y = points[r[z + 1] - 1][1];
// 처음에만 시작 위치 포함
if (z == 0)
rtmp.push_back({ before_x,before_y });
int k = before_x;
int l = before_y;
if (before_x < next_x) // 아래로
{
k += 1;
for (;k <= next_x;k++)
rtmp.push_back({ k,before_y });
}
else if (before_x > next_x) // 위로
{
k -= 1;
for (;k >= next_x;k--)
rtmp.push_back({ k,before_y });
}
if (before_y < next_y) // 우로만
{
l += 1;
for (;l <= next_y;l++)
rtmp.push_back({ next_x,l });
}
else if (before_y > next_y) // 좌로만
{
l -= 1;
for (;l >= next_y;l--)
rtmp.push_back({ next_x,l });
}
}
route[i + 1] = rtmp;
}
int max_len = 0;
for (int i = 0;i < x;i++)
if (max_len < route[i + 1].size())
max_len = route[i + 1].size();
// 최대 좌표 이동 횟수
for (int k = 0;k < max_len;k++)
{
// 로봇의 수 (좌표 출현 갯수) -> second(int)의 값이>1인 경우 answer++;
map<pair<int, int>, int> loc_cnt;
for (int a = 0;a < x;a++)
if (route[a + 1].size() > k)
loc_cnt[{route[a + 1][k].first, route[a + 1][k].second}]++;
for (auto iter = loc_cnt.begin();iter != loc_cnt.end();iter++)
if (iter->second > 1) answer++;
}
return answer;
}
굳이 상하 -> 좌우 를 중첩 조건문으로 풀어내지 않고, 순차로 처리하도록 하였다. 그리고 else 가 아니라 else if 로 이동하지 않는 경우에 대해서는 배제한다. 그 뒤에 최대 좌표 이동 횟수를 계산하는 로직을 기존과 동일