.https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5V61LqAf8DFAWu
시뮬레이션 문제.
문제만 처음 봤을 때는 전체 다 순회하려면 시간이 오래 걸릴 것이라고 생각했다.
근데 전체 MAP 크기가 20*20 밖에 안되고 각 포인트에서 다른 포인트까지의 거리(20*20)와 거리마다의 집 수를 기록해놓고 최대 집 개수와 비교했다.
결국 마름모 모양이라는 것은 시작점을 기준으로 (K=2)라면 거리 차이가 1 이하인 점들, (K=4)라면 거리 차이가 3 이하인 점들을 모아놓은 것이라서 한 점을 기준으로 거리마다의 집 수를 구하고 그를 이용해서 수익을 계산해주었다.
O(N^5)의 풀이가 나왔지만 최대 N이 20이라서 여유롭게 통과할 수 있었음.
아래는 코드
#include <cstdio>
#include <stdlib.h>
#include <string.h>
//INPUT이 길 경우 파일로 인풋을 받음
FILE* in = fopen("input.txt", "r");
int t, n, m;
int map[21][21];
int sol[39];
int max;
int max_house;
void cost(int a, int b) {
//거리에 따른 집의 수*수익 초기화
memset(sol, 0, sizeof(sol));
//가장 멀리 있는 집의 거리가 얼마인지
max = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
//거리에 따라 값 더해주기
sol[abs(a-i) + abs(b - j)] += map[i][j];
//집이 있는 가장 먼 거리 갱신
if (max < abs(a - i) + abs(b - j) && map[i][j] != 0)
{
max = abs(a - i) + abs(b - j);
}
}
}
//만약 최대 집 수가 0이고 기준점에 집이 존재한다면 최대 집 수를 1로 갱신
//집 당 수익이 1 이상이기 때문에 (K=1)일 때 집이 존재한다면 무조건 손해가 아니다.
if (map[a][b] > 0 && max_house == 0)
max_house = 1;
//손해가 아닐 때 최대의 집 수를 갱신
for (int i = 1; i <= max; i++)
{
sol[i] = sol[i] + sol[i - 1];
if (sol[i] - (i * i + (i + 1) * (i + 1)) >= 0)
{
if (max_house < (sol[i] / m))
max_house = sol[i] / m;
}
}
}
int main() {
fscanf(in, "%d", &t);
for (int i = 0; i < t; i++)
{
max_house = 0;
fscanf(in, "%d %d", &n, &m);
for (int j = 0; j < n; j++)
{
for (int k = 0; k < n; k++)
{
int a;
fscanf(in, "%d", &a);
map[j][k] = a * m;
}
}
//MAP 상의 모든 점을 돌면서 최대 집 수 계산
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
cost(j, k);
printf("#%d %d\n",i+1 ,max_house);
}
return 0;
}
'알고리즘 > SW Expert Academy' 카테고리의 다른 글
[SW Expert Academy] 2115. 벌꿀 채취 C/C++ 풀이 (0) | 2020.08.09 |
---|---|
백준 14500번 테트로미노 C/C++ 풀이 (0) | 2020.08.08 |
[SW Expert Academy] 5648. 원자 소멸 시뮬레이션 C/C++ 풀이 (0) | 2020.08.05 |
[SW Expert Academy] 2382. 미생물 격리 C/C++ 풀이 (0) | 2020.08.04 |