문제 설명
P, O, X로 이루어진 문자열 배열이 주어지고,
P는 응시자가 앉아있는 자리,
O는 빈 테이블,
X는 파티션을 의미합니다.
파티션을 사이에 두고 거리두기를 지켰는지 확인하는 문제입니다.
문제 풀이
파티션이 없는 경우 최소 2 이하로 붙으면 거리두기를 지키지 않은 것으로 확인합니다.
ex) POPOO -> 지키지 않은 경우, POOPO -> 거리두기를 지킨 경우
대각선 1칸은 거리 2로 계산합니다.
우선 P의 왼쪽은 비교할 필요가 없습니다.
PXPXP로 1줄을 오른쪽만 체크한다고 가정하면
왼쪽 P는 중간에 P가 있지만 가림막이 있어서 통과하고,
중간의 P도 오른쪽 P가 있지만 가림막이 있어서 통과입니다.
오른쪽 P는 이미 중간(오른쪽 P의 왼쪽)의 P와 비교했고, 오른쪽은 막혔습니다.
그럼 오른쪽만 체크한다고 하면 0, 1, 2, 3 열의 P만 체크하면 됩니다.
같은 원리로 위쪽도 체크할 필요가 없습니다.
아래쪽의 0, 1, 2, 3 행의 P만 체크하면 됩니다.
대각선은
0, 0부터 3, 3까지 오른쪽 아래만 체크,
0, 4부터 3, 1까지 왼쪽 아래만 체크하면 됩니다.
오른쪽만 체크, 아래만 체크, 오른쪽 아래만 체크, 왼쪽 아래만 체크로
체크하는 작업 단위를 나눠서 모든 응시자의 거리두기를 체크할 수 있습니다.
제출 코드
using System;
public class Solution
{
public int[] solution(string[,] places)
{
int[] answer = new int[5];
for (int i = 0; i < 5; i++)
{
string[,] matrix = new string[5, 5];
answer[i] = 1;
bool possible = true;
// matrix 생성
for (int j = 0; j < 5; j++)
{
for (int k = 0; k < 5; k++)
{
string s = "" + places[i, j][k];
matrix[j, k] = s;
}
}
// check right
for (int j = 0; j < 5; j++)
{
for (int k = 0; k < 4; k++)
{
if (matrix[j, k] == "P")
{
string X = k + 2 == 5 ? "X" : matrix[j, k + 2];
if (!CheckRight(matrix[j, k + 1], X))
{
possible = false;
j = 5;
break;
}
}
}
}
if (!possible)
{
answer[i] = 0;
continue;
}
// check bottom
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 5; k++)
{
if (matrix[j, k] == "P")
{
string X = j + 2 == 5 ? "X" : matrix[j + 2, k];
if (!CheckRight(matrix[j + 1, k], X))
{
possible = false;
j = 5;
break;
}
}
}
}
if (!possible)
{
answer[i] = 0;
continue;
}
// check right diagonal
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 4; k++)
{
if (matrix[j, k] == "P")
{
if (!CheckDiagonal(matrix[j + 1, k + 1], matrix[j, k + 1], matrix[j + 1, k]))
{
possible = false;
j = 5;
break;
}
}
}
}
if (!possible)
{
answer[i] = 0;
continue;
}
// check left diagonal
for (int j = 0; j < 4; j++)
{
for (int k = 4; k > 0; k--)
{
if (matrix[j, k] == "P")
{
if (!CheckDiagonal(matrix[j + 1, k - 1], matrix[j, k - 1], matrix[j + 1, k]))
{
possible = false;
j = 5;
break;
}
}
}
}
if (!possible)
{
answer[i] = 0;
continue;
}
}
return answer;
}
bool CheckRight(string right1, string right2)
{
if (right1 == "P") return false;
if (right2 == "P")
{
if (right1 == "X")
{
return true;
}
else
{
return false;
}
}
return true;
}
bool CheckBottom(string bottom1, string bottom2)
{
if (bottom1 == "P") return false;
if (bottom2 == "P")
{
if (bottom1 == "X")
{
return true;
}
else
{
return false;
}
}
return true;
}
bool CheckDiagonal(string diagonal, string LR, string bottom)
{
if (diagonal == "P")
{
if (LR == "X" && bottom == "X")
{
return true;
}
else
{
return false;
}
}
return true;
}
}