알고리즘/SWEA

SWEA 모의 5648 원자소멸시뮬레이션

  • -
반응형

SWEA 모의 5648 원자소멸시뮬레이션

 

 

문제링크

http://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRFInKex8DFAUo

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

* 일단 문제를 정독 하고 1시간 이상 반드시 고민이 필요합니다.

 

동영상 설명

1시간 이상 고민 했지만 아이디어가 떠오르지 않는다면 동영상에서 약간의 힌트를 얻어봅시다.

 

소스 보기

동영상 설명을 보고도 전혀 구현이 안된다면 이건 연습 부족입니다.
소스를 보고 작성해 본 후 스스로 백지 상태에서 3번 작성해 볼 의지가 있다면 소스를 살짝 보세요.

더보기
package se.code.모의;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

public class SWEA_모의_5648_원자소멸시뮬레이션 {
    static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    static StringBuilder output = new StringBuilder();

    static int TC;

    static int N;// 원자의 개수: (1≤N≤1,000)

    // 이동 방향
    static int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3;

    static int E;

    // 전체 원자의 목록
    static List<Atom> list = new LinkedList<>();

    // 이동된 원자들을 지점을 기반으로 목록으로 관리하기 위한 맵
    static Map<Integer, List<Atom>> moveMap = new HashMap<>();

    // 매 텀이 끝나고 지울 원자의 목록: 지우는 대상은 범위를 벗어나거나, 충돌해서 없어진 것들
    static List<Atom> delList = new LinkedList<>();

    public static void main(String[] args) throws IOException {
        input = new BufferedReader(new StringReader(src));

        TC = Integer.parseInt(input.readLine());

        StringTokenizer tokens = null;
        for (int t = 1; t <= TC; t++) {
            N = Integer.parseInt(input.readLine());

            list.clear();
            for (int n = 0; n < N; n++) {
                tokens = new StringTokenizer(input.readLine(), " ");
                // 0.5초 단위로 이동시키기 위해서 좌표를 2배로 뻥튀기
                int col = (Integer.parseInt(tokens.nextToken())) * 2;
                int row = (Integer.parseInt(tokens.nextToken())) * 2;

                int dir = Integer.parseInt(tokens.nextToken());
                int power = Integer.parseInt(tokens.nextToken());

                list.add(new Atom(row, col, dir, power));
            }
            /*
            System.out.println("원자 목록");
            System.out.println(list);
            */
            // 총 에너지 목록
            E = 0;
            while (true) {
                // System.out.println(list.size());
                if (list.size() <= 1) {
                    break;
                }
                moveMap.clear();
                delList.clear();
                for (Atom a : list) {
                    a.move();
                    if (!isIn(a)) {
                        // 범위를 벗어난다면 바로 삭제 대상!!
                        // System.out.println("범위 밖이야: " + a);
                        delList.add(a);
                        continue;
                    } else {
                        // 범위 안에 있는 녀석들은 map에서 관리
                        putToMoveMap(a);
                    }
                }
                checkCrash();
                // System.out.println("삭제 대상: " + delList);
                list.removeAll(delList);
            }
            output.append("#").append(t).append(" ").append(E).append("\n");
        }
        System.out.println(output);
    }

    static void checkCrash() {
        Set<Integer> keys = moveMap.keySet();
        for (Integer key : keys) {
            List<Atom> list = moveMap.get(key);
            if (list.size() > 1) {
                for (Atom a : list) {
                    E += a.power;
                    delList.add(a);
                }
            }
        }
    }

    static void putToMoveMap(Atom a) {
        // 이차원 배열의 키값을 int로 처리 하기 위한 처리
        Integer key = a.row * 4001 + a.col;
        if (moveMap.containsKey(key)) {
            moveMap.get(key).add(a);
        } else {
            List<Atom> atoms = new ArrayList<>();
            atoms.add(a);
            moveMap.put(key, atoms);
        }
    }

    static boolean isIn(Atom a) {
        return -2000 <= a.row && a.row <= 2000 && -2000 <= a.col && a.col <= 2000;
    }

    static class Atom {
        int row, col, dir, power;

        public Atom(int row, int col, int dir, int power) {
            super();
            this.row = row;
            this.col = col;
            this.dir = dir;
            this.power = power;
        }

        public void move() {
            if (dir == UP) {
                row++;
            } else if (dir == DOWN) {
                row--;
            } else if (dir == RIGHT) {
                col++;
            } else {
                col--;
            }
        }

        @Override
        public String toString() {
            return "Atom [row=" + row + ", col=" + col + ", dir=" + dir + ", power=" + power + "]";
        }
    }

    private static String src = "2\r\n" +
                                "4\r\n" +
                                "-1000 0 3 5\r\n" +
                                "1000 0 2 3\r\n" +
                                "0 1000 1 7\r\n" +
                                "0 -1000 0 9\r\n" +
                                "4\r\n" +
                                "-1 1 3 3\r\n" +
                                "0 1 1 1\r\n" +
                                "0 0 2 2\r\n" +
                                "-1 0 0 9";


}

 

반응형

'알고리즘 > SWEA' 카테고리의 다른 글

SWEA 모의 2105 디저트 카페  (0) 2020.05.29
SWEA 모의 2112 보호필름  (0) 2020.05.27
SWEA D4 7206 숫자게임  (0) 2020.05.23
SWEA 모의 5644 무선충전  (0) 2020.05.21
SWEA D3 2806 NQueen  (1) 2020.05.09
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.