마법사 상어와 파이어볼
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 512 MB | 876 | 292 | 189 | 31.086% |
문제
어른 상어가 마법사가 되었고, 파이어볼을 배웠다.
마법사 상어가 크기가 N×N인 격자에 파이어볼 M개를 발사했다. 가장 처음에 파이어볼은 각자 위치에서 이동을 대기하고 있다. i번 파이어볼의 위치는 (ri, ci), 질량은 mi이고, 방향은 di, 속력은 si이다. 위치 (r, c)는 r행 c열을 의미한다.
격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다.
파이어볼의 방향은 어떤 칸과 인접한 8개의 칸의 방향을 의미하며, 정수로는 다음과 같다.
7 | 0 | 1 |
---|---|---|
6 | 2 | |
5 | 4 | 3 |
마법사 상어가 모든 파이어볼에게 이동을 명령하면 다음이 일들이 일어난다.
모든 파이어볼이 자신의 방향 d
i
로 속력 s
i
칸 만큼 이동한다.
- 이동하는 중에는 같은 칸에 여러 개의 파이어볼이 있을 수도 있다.
이동이 모두 끝난 뒤, 2개 이상의 파이어볼이 있는 칸에서는 다음과 같은 일이 일어난다.
같은 칸에 있는 파이어볼은 모두 하나로 합쳐진다.
파이어볼은 4개의 파이어볼로 나누어진다.
나누어진 파이어볼의 질량, 속력, 방향은 다음과 같다.
- 질량은 ⌊(합쳐진 파이어볼 질량의 합)/5⌋이다.
- 속력은 ⌊(합쳐진 파이어볼 속력의 합)/(합쳐진 파이어볼의 개수)⌋이다.
- 합쳐지는 파이어볼의 방향이 모두 홀수이거나 모두 짝수이면, 방향은 0, 2, 4, 6이 되고, 그렇지 않으면 1, 3, 5, 7이 된다.
질량이 0인 파이어볼은 소멸되어 없어진다.
마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 구해보자.
입력
첫째 줄에 N, M, K가 주어진다.
둘째 줄부터 M개의 줄에 파이어볼의 정보가 한 줄에 하나씩 주어진다. 파이어볼의 정보는 다섯 정수 ri, ci, mi, si, di로 이루어져 있다.
서로 다른 두 파이어볼의 위치가 같은 경우는 입력으로 주어지지 않는다.
출력
마법사 상어가 이동을 K번 명령한 후, 남아있는 파이어볼 질량의 합을 출력한다.
제한
- 4 ≤ N ≤ 50
- 0 ≤ M ≤ N2
- 1 ≤ K ≤ 1,000
- 1 ≤ ri, ci ≤ N
- 1 ≤ mi ≤ 1,000
- 1 ≤ si ≤ 1,000
- 0 ≤ di ≤ 7
예제 입력 1 복사
xxxxxxxxxx
4 2 1
1 1 5 2 2
1 4 7 1 6
예제 출력 1 복사
xxxxxxxxxx
8
예제 입력 2 복사
xxxxxxxxxx
4 2 2
1 1 5 2 2
1 4 7 1 6
예제 출력 2 복사
xxxxxxxxxx
8
예제 입력 3 복사
xxxxxxxxxx
4 2 3
1 1 5 2 2
1 4 7 1 6
예제 출력 3 복사
xxxxxxxxxx
0
예제 입력 4 복사
xxxxxxxxxx
7 5 3
1 3 5 2 4
2 3 5 2 6
5 2 9 1 7
6 2 1 3 5
4 4 2 4 2
예제 출력 4 복사
9
풀이
삼성 코테 문제
지문 중
격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다.
이런 지문이 있다.
지문 해석하기가 너무 힘들었다 ㅠ
예를 들어서 N = 3 인 3x3 격자가 있다면
(1,1) (1,2) (1,3)
(2,1) (2,2) (2,3)
(3,1) (3,2) (3,3)
이렇게 표시 될 것인데
1,1 에서 위로 한칸 이동하면 보통의 경우는 맵 범위 밖으로 나갔다고 처리를 하지만
1,1 에서 위로 한칸을 가면 3,1에 파이어볼이 도착하고 마찬가지로
3,1에서 아래로 한 칸을 가면 1,1에 도착한다.
1,3에서 오른쪽으로 한 칸 가는 것 또한 1,1 로 도착하고
1,1 에서 왼쪽으로 한 칸 이동하는 것 또한 1,3 으로 도착 한다고 설정해주면 된다.
나는 파이어볼을 맵에다가 배치했는데 한 칸에 파이어볼이 여러개 있을 수 있으니
2차원 배열 리스트를 사용했다.
이렇게하면 map[x] [y] 좌표에 여러개의 파이어볼 객체를 넣어줄 수 있다.
우선 파이어볼의 정보를 가지고 있는 클래스를 정의 해주자.
class Node{
int m,d,s;
Node(int m , int s, int d){
this.m=m;
this.d=d;
this.s=s;
}
}
파이어볼의 정보중 무게(m) 방향 (d) 속도 (s) 를 갖고 있는 클래스를 만들어 준다.
그 다음 2차원 연결리스트를 만들어준다.
static LinkedList<Node>map[][];
static LinkedList<Node>copy_map[][];
for(int i=0; i<=n; i++) {
for(int j=0; j<=n; j++) {
map[i][j] = new LinkedList<>();
copy_map[i][j] = new LinkedList<>();
}
}
그 다음 맵의 입력으로 주어지는 x,y좌표 무게 속도 방향을 해당 칸에다가 넣어준다.
for(int i=0; i<m; i++) {
String [] tt = br.readLine().split(" ");
int r = Integer.parseInt(tt[0]);
int c = Integer.parseInt(tt[1]);
int m = Integer.parseInt(tt[2]);
int s = Integer.parseInt(tt[3]);
int d = Integer.parseInt(tt[4]);
map[r][c].add(new Node(m,s,d));
}
이제 맵을 순회하면서 해당 칸에 파이어볼이 있는지 없는 지를 체크하고
조건에서 시키는 대로 하면 된다.
그 중 주의해야 할 점은
문제 조건중 모든 파이어볼이 자신의 방향 di로 속력 si칸 만큼 이동한다
이란 부분이 있다.
여기서 (1,1)에서 위로 1칸을 이동하면 (3,1)이 된다는 것을 알 수 있다.
근데 문제의 조건 중 명령의 종류 K는 최대 1000, 이동 할 수 있는 거리(속도)는 최대 1000
파이어볼의 개수 최대 250 을 다 하면
1초안에 들어오지 못할 수 있다.
그래서 움직이는 횟수를 나누기 연산으로 구해주면 된다.
전체코드
import java.io.*;
import java.util.*;
public class Main {
static int n,m,k;
static LinkedList<Node>map[][];
static LinkedList<Node>copy_map[][];
static int dx[] ={-1,-1,0,1,1,1,0,-1};
static int dy[] = {0,1,1,1,0,-1,-1,-1};
static ArrayList<Integer>dir = new ArrayList<>();
static int ans = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String [] t = br.readLine().split(" ");
n = Integer.parseInt(t[0]);
m = Integer.parseInt(t[1]);
k = Integer.parseInt(t[2]);
map = new LinkedList[n+1][n+1];
copy_map = new LinkedList[n+1][n+1];
for(int i=0; i<=n; i++) {
for(int j=0; j<=n; j++) {
map[i][j] = new LinkedList<>();
copy_map[i][j] = new LinkedList<>();
}
}
for(int i=0; i<m; i++) {
String [] tt = br.readLine().split(" ");
int r = Integer.parseInt(tt[0]);
int c = Integer.parseInt(tt[1]);
int m = Integer.parseInt(tt[2]);
int s = Integer.parseInt(tt[3]);
int d = Integer.parseInt(tt[4]);
map[r][c].add(new Node(m,s,d));
}
for(int i=0; i<k; i++) {
solve();
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(map[i][j].size()!=0) {
int size = map[i][j].size();
for(int k=0; k<size; k++) {
Node a = map[i][j].poll();
ans += a.m;
}
}
}
}
System.out.println(ans);
}
public static void solve() {
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(map[i][j].size()!=0) {
int size = map[i][j].size();
for(int k=0; k<size; k++) {
Node a = map[i][j].poll();
int x = i;
int y = j;
int d = a.d;
int s = a.s;
int m = a.m;
int move_cnt = s%n;
x+=(dx[d]*move_cnt);
y+=(dy[d]*move_cnt);
if(x<1) {
x = n+x;
}
else if(x>n) {
x = x-n;
}
if(y<1) {
y = n+y;
}
else if(y>n) {
y = y-n;
}
copy_map[x][y].add(new Node(m,s,d));
}
}
}
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
if(copy_map[i][j].size()!=0) {
int size = copy_map[i][j].size();
for(int k=0; k<size; k++) {
Node a= copy_map[i][j].poll();
map[i][j].add(a);
}
}
}
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
int tmp_m =0;
int tmp_s = 0;
int cnt = 0;
if(map[i][j].size()>1) {
dir.clear();
int size = map[i][j].size();
for(int k=0; k<size; k++) {
Node a = map[i][j].poll();
tmp_m+=a.m;
tmp_s+=a.s;
dir.add(a.d);
cnt++;
}
tmp_m/=5;
tmp_s/=cnt;
if(tmp_m >0) {
int [] dir = get_dir();
for(int z=0; z<4; z++) {
map[i][j].add(new Node(tmp_m,tmp_s,dir[z]));
}
}
}
}
}
}
public static int[] get_dir() {
int a[] = new int[4];
boolean flag = true;
for(int i=0; i<dir.size(); i++) {
if(dir.get(i)%2==0) {
flag = false;
}
}
if(flag) {
a[0] = 0;
a[1] =2;
a[2] =4;
a[3] = 6;
return a;
}
flag = true;
for(int i=0; i<dir.size(); i++) {
if(dir.get(i)%2!=0) {
flag = false;
}
}
if(flag) {
a[0] = 0;
a[1] =2;
a[2] =4;
a[3] = 6;
return a;
}
a[0] = 1;
a[1] = 3;
a[2] = 5;
a[3] = 7;
return a;
}
}
class Node{
int m,d,s;
Node(int m , int s, int d){
this.m=m;
this.d=d;
this.s=s;
}
}
'알고리즘' 카테고리의 다른 글
[백준 15904] UCPC는 무엇의 약자일까? (2) | 2020.12.27 |
---|---|
[백준 15903] 카드합체놀이 -JAVA // le_effort (1) | 2020.12.27 |
[백준 20055] 컨베이어 벨트 위의 로봇 (0) | 2020.11.10 |
[백준 20057] 마법사 상어와 토네이도 (0) | 2020.11.05 |
[프로그래머스] 구명보트 -JAVA (0) | 2020.09.11 |