땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • ㅗ
  • D
  • I
  • 이것이 리눅스다 with Rocky Linux9
  • E

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

Algorithm/Algorithm Problem

백준 17143 낚시왕 (구현, 시뮬레이션)

2022. 10. 5. 14:44
 

17143번: 낚시왕

낚시왕이 상어 낚시를 하는 곳은 크기가 R×C인 격자판으로 나타낼 수 있다. 격자판의 각 칸은 (r, c)로 나타낼 수 있다. r은 행, c는 열이고, (R, C)는 아래 그림에서 가장 오른쪽 아래에 있는 칸이다.

www.acmicpc.net

 

SW Expert Academy

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

swexpertacademy.com

 

삼성 SW 역량 테스트 기출 문제랑 매우 유사한 문제이다.

 

상어가 움직이면서 다른상어를 잡아먹고 방향대로 이동하고 그대로 구현하면 되는 시뮬레이션 문제이다.

 

여기서 포인트는

1. 상어가 움직일 때 for 속력해서 하나하나 잡아주게 되면 시간초과가 난다. 

2. 상어들이 움직인 다음에 다른 상어를 잡아먹을 때 크기에 대해 대소비교를 해줘야함

 

1. 상,하 / 좌,우 에 대해서 좌표압축을 할 수 있다.

 

int temp_dir = shark[j][3];
int temp = temp_dir < 2 ? R : C;
int move_length = shark[j][2] % ((temp-1) * 2);

 

따라서 move_length에 대해서만 상어가 이동을 해주면 시간초과가 안난다.

 

2. 상어객체가 담긴 List or Array를 for돌려서 하나씩 꺼내서 이동을 해줄텐데 처음부터 크기에 대해서

내림차순 정렬을 해버리면 뒤에 나오는 상어들은 처음에 나온 상어보다 크기가 작기 때문에 잡아먹을 일 X

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/* 이거 SWEA 미생물 문제랑 똑같음
* y >= C면 이동을 멈춤
*
* 1. 오른쪽으로 한칸 이동
* 2. col탐색 하면서 가장 idx가 작은 상어를 잡는다. board에서 상어는 사라짐
* 3. 다른 상어들이 이동
* 
* 상어가 이동하려고 하는 칸이 격자판의 경계를 넘는 경우에는 방향을 반대로 바꿔서 속력을 유지한채로 이동
*크기가 가장 큰 상어가 나머지 상어를 모두 잡아먹는다(그러면 가장 큰 상어를 기준으로 정렬한다음 걔를 기준으로 하면 되지 않을까?)
*
* */

public class Main_17143 {
    static int R,C,M,res;
    static int[][] shark;
    static int[] dx = {-1,1,0,0}; //상하우좌
    static int[] dy = {0,0,1,-1};
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        shark = new int[M][5];

        //shark : x,y,속력, 방향, 크기, 존재여부
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int r = Integer.parseInt(st.nextToken());
            int c = Integer.parseInt(st.nextToken());
            int s = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());
            int z = Integer.parseInt(st.nextToken());
            shark[i] = new int[]{r,c,s,d-1,z,1};
        }

        //가장 큰 상어부터 고려하면 다음 상어가 오더라도 덮어쓰기 가능
        Arrays.sort(shark,(o1, o2) -> (o2[4] - o1[4]));



        for (int i = 1; i < C+1; i++) { //총 C만큼만 이동하니까
            //System.out.println(i+"초");
            List<Integer>[][] board = new ArrayList[R+1][C+1];
            for (int j = 1; j < R+1; j++) {
                for (int k = 1; k < C+1; k++) {
                    board[j][k] = new ArrayList<>();
                }
            }

            //상어 잡기
            PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> (o1[0] - o2[0]));
            for (int j = 0; j < M; j++) {
                if (shark[j][1] == i && shark[j][5]==1){
                    pq.add(shark[j]);
                }
            }
            int[] catch_shark = pq.poll(); //take_shark 위에 값 덮어씌워도 가능(shallow copy라서)
            if (catch_shark != null){
                //System.out.println(Arrays.toString(catch_shark));
                catch_shark[5] = 0;
                res += catch_shark[4];
            }

            //상어 이동
            for (int j = 0; j < M; j++) {
                if (shark[j][5] == 1){ //살아있는 애들만
                    //System.out.println(shark[j][0]+" "+shark[j][1]);
                    int temp_dir = shark[j][3];
                    int temp = temp_dir < 2 ? R : C;
                    int move_length = shark[j][2] % ((temp-1) * 2);

                    //System.out.println("move_length : " + move_length);
                    for (int k = 0; k < move_length; k++) { //전진
                        int dir = shark[j][3];
                        int x = shark[j][0];
                        int y = shark[j][1];

                        int nx = x + dx[dir];
                        int ny = y + dy[dir];
                        //System.out.println("방향 전 : "+dir);

                        if (nx == 0 || ny == 0 || nx == R+1 || ny == C+1){
                            shark[j][3] = reverse_dir(shark[j]);
                            shark[j][0] = x + dx[shark[j][3]];
                            shark[j][1] = y + dy[shark[j][3]];
                            //System.out.println("방향 후 : "+shark[j][3]);
                        }
                        else{
                        shark[j][0] = nx;
                        shark[j][1] = ny;
                        }
                    }
                    //System.out.println(Arrays.toString(shark[j]));
                    //System.out.println();
                    board[shark[j][0]][shark[j][1]].add(j+1);
                }
            }

            //이동을 마친 후에 상어 2마리가 겹친다면?
            for (int j = 1; j < R+1; j++) {
                for (int k = 1; k < C+1; k++) {
                    if (board[j][k].size() > 1){
                        //print();
                        //System.out.println(j+" "+k);
                        //System.out.println("겹친다");

                        for (int l = 1; l < board[j][k].size(); l++) {
                            int index = board[j][k].get(l);
                            //System.out.println(Arrays.toString(shark[index-1]));
                            shark[index-1][5] = 0;
                        }
                    }

                }
            }
            //print();


        }
        System.out.println(res);




    }
    public static void print(){
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < 6; j++) {
                System.out.print(shark[i][j]+" ");
            }
            System.out.println();
        }
    }


    public static int reverse_dir(int[] shark) {
        int dir = shark[3];

        switch (dir){
            case 0:
                shark[3] = 1;
                break;
            case 1:
                shark[3] = 0;
                break;
            case 2:
                shark[3] = 3;
                break;
            case 3:
                shark[3] = 2;
                break;
        }
        return shark[3];
    }
}

 

'Algorithm > Algorithm Problem' 카테고리의 다른 글

백준 2056 작업(위상정렬, DP) ★★  (0) 2022.10.07
SWEA 7793 오! 나의 여신님 (BFS)  (1) 2022.10.06
SWEA 1953 탈주범 검거(BFS, 구현)  (1) 2022.09.30
SWEA 1952 수영장(DFS, DP)  (0) 2022.09.28
백준 19238 스타트 택시(BFS, 구현)  (0) 2022.09.20
    'Algorithm/Algorithm Problem' 카테고리의 다른 글
    • 백준 2056 작업(위상정렬, DP) ★★
    • SWEA 7793 오! 나의 여신님 (BFS)
    • SWEA 1953 탈주범 검거(BFS, 구현)
    • SWEA 1952 수영장(DFS, DP)
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바