알고리즘 풀이/백준(Boj)

백준(BOJ) 17143번 낚시왕

100win10 2019. 12. 19. 14:43

문제 : https://www.acmicpc.net/problem/17143

 

17143번: 낚시왕

낚시왕이 상어 낚시를 하는 곳은 크기가 R×C인 격자판으로 나타낼 수 있다. 격자판의 각 칸은 (r, c)로 나타낼 수 있다. r은 행, c는 열이고, (R, C)는 아래 그림에서 가장 오른쪽 아래에 있는 칸이다. 칸에는 상어가 최대 한 마리 들어있을 수 있다. 상어는 크기와 속도를 가지고 있다. 낚시왕은 처음에 1번 열의 한 칸 왼쪽에 있다. 다음은 1초 동안 일어나는 일이며, 아래 적힌 순서대로 일어난다. 낚시왕은 가장 오른쪽 열의 오른쪽 칸에 이동하

www.acmicpc.net

풀이 :

 

속도 배열, 크기 배 열등을 tuple로 한꺼번에 모아서 처리해보았다.

 

<상어가 존재하는지, 속도, 방향, 크기 >를 나타낸다. 옮길 때에는 옮긴 상어들끼리의 비교를 위해

 

copy 배열을 만들어서 그곳에 옮긴 후 다시 a로 옮기는 방식으로 하였다.

 

코드 ( C++ )

#include <iostream>
#include <tuple>
#include <cstring>
using namespace std;
tuple<int, int, int, int> a[100][100];
tuple<int, int, int, int> cop[100][100];
int R, C, m;
void moveUp(int y, int x, int speed)
{
int temp, s1, d1, z1;
tie(temp, s1, d1, z1) = a[y][x];
int d = -1;
int ny = y;
while (speed != 0)
{
ny += d;
if (ny < 0) {
ny += 2;
d = 1;
}
else if (ny > R - 1) {
ny -= 2;
d = -1;
}
speed--;
}
int isShark, s2, d2, z2;
tie(isShark, s2, d2, z2) = cop[ny][x];
//newd는 따로 구해야함
int newd = d > 0 ? 2 : 1;
//옮긴 곳에 상어가 있다면
if (isShark) {
// 옮긴 상어가 더 클때
if (z1 > z2) {
cop[ny][x] = { 1,s1,newd,z1 };
}
else
cop[ny][x] = { 1,s2,d2,z2 };
}
else {
cop[ny][x] = { temp,s1,newd,z1 };
}
a[y][x] = { 0,0,0,0 };
}
void moveDown(int y, int x, int speed)
{
int temp, s1, d1, z1;
tie(temp, s1, d1, z1) = a[y][x];
int d = 1;
int ny = y;
while (speed != 0)
{
ny += d;
if (ny < 0) {
ny += 2;
d = 1;
}
else if (ny > R - 1) {
ny -= 2;
d = -1;
}
speed--;
}
int isShark, s2, d2, z2;
tie(isShark, s2, d2, z2) = cop[ny][x];
//newd는 따로 구해야함
int newd = d > 0 ? 2 : 1;
//옮긴 곳에 상어가 있다면
if (isShark) {
// 옮긴 상어가 더 클때
if (z1 > z2) {
cop[ny][x] = { 1,s1,newd,z1 };
}
else
cop[ny][x] = { 1,s2,d2,z2 };
}
else {
cop[ny][x] = { temp,s1,newd,z1 };
}
a[y][x] = { 0,0,0,0 };
}
void moveLeft(int y, int x, int speed)
{
int temp, s1, d1, z1;
tie(temp, s1, d1, z1) = a[y][x];
int d = -1;
int nx = x;
while (speed != 0)
{
nx += d;
if (nx < 0) {
nx += 2;
d = 1;
}
else if (nx > C - 1) {
nx -= 2;
d = -1;
}
speed--;
}
int isShark, s2, d2, z2;
tie(isShark, s2, d2, z2) = cop[y][nx];
//newd는 따로 구해야함
int newd = d > 0 ? 3 : 4;
//옮긴 곳에 상어가 있다면
if (isShark) {
// 옮긴 상어가 더 클때
if (z1 > z2) {
cop[y][nx] = { 1,s1,newd,z1 };
}
else
cop[y][nx] = { 1,s2,d2,z2 };
}
else {
cop[y][nx] = { temp,s1,newd,z1 };
}
a[y][x] = { 0,0,0,0 };
}
void moveRight(int y, int x, int speed)
{
int temp, s1, d1, z1;
tie(temp, s1, d1, z1) = a[y][x];
int d = 1;
int nx = x;
while (speed != 0)
{
nx += d;
if (nx < 0) {
nx += 2;
d = 1;
}
else if (nx > C - 1) {
nx -= 2;
d = -1;
}
speed--;
}
int isShark, s2, d2, z2;
tie(isShark, s2, d2, z2) = cop[y][nx];
//newd는 따로 구해야함
int newd = d > 0 ? 3 : 4;
//옮긴 곳에 상어가 있다면
if (isShark) {
// 옮긴 상어가 더 클때
if (z1 > z2) {
cop[y][nx] = { 1,s1,newd,z1 };
}
else
cop[y][nx] = { 1,s2,d2,z2 };
}
else {
cop[y][nx] = { temp,s1,newd,z1 };
}
a[y][x] = { 0,0,0,0 };
}
int main()
{
cin >> R >> C >> m;
for (int i = 0; i < m; ++i)
{
int r, c, s, d, z;
cin >> r >> c >> s >> d >> z;
// 상어 표시
a[r - 1][c - 1] = { 1,s,d,z };
}
int person = 0;
int ans = 0;
while (1) {
if (person >= C) break;
memset(cop, 0, sizeof(cop));
//낚시왕이 낚시를 한다.
for (int i = 0; i < R; ++i)
{
int isShark, s, d, z;
tie(isShark, s, d, z) = a[i][person];
if (isShark) {
ans += z;
a[i][person] = { 0,0,0,0 };
break;
}
}
// 상어들이 이동한다.
for (int i = 0; i < R; ++i)
for (int j = 0; j < C; ++j)
{
int isShark, s, d, z;
tie(isShark, s, d, z) = a[i][j];
if (isShark) {
if (d == 1)
moveUp(i, j, s);
else if (d == 2)
moveDown(i, j, s);
else if (d == 3)
moveRight(i, j, s);
else
moveLeft(i, j, s);
}
}
for (int i = 0; i < R; ++i)
for (int j = 0; j < C; ++j)
a[i][j] = cop[i][j];
person++;
}
cout << ans << "\n";
return 0;
}
view raw .cpp hosted with ❤ by GitHub