algorithm

BOJ 17143

rkawk 2022. 10. 13. 18:22

문제

더보기

λ‚šμ‹œμ™• μ„±κ³΅

 
1 초 512 MB 38078 11153 6336 25.940%

문제

λ‚šμ‹œμ™•μ΄ 상어 λ‚šμ‹œλ₯Ό ν•˜λŠ” 곳은 크기가 R×C인 격자판으둜 λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€. 격자판의 각 칸은 (r, c)둜 λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€. r은 ν–‰, cλŠ” 열이고, (R, C)λŠ” μ•„λž˜ κ·Έλ¦Όμ—μ„œ κ°€μž₯ 였λ₯Έμͺ½ μ•„λž˜μ— μžˆλŠ” 칸이닀. μΉΈμ—λŠ” 상어가 μ΅œλŒ€ ν•œ 마리 λ“€μ–΄μžˆμ„ 수 μžˆλ‹€. μƒμ–΄λŠ” 크기와 속도λ₯Ό κ°€μ§€κ³  μžˆλ‹€.

λ‚šμ‹œμ™•μ€ μ²˜μŒμ— 1번 μ—΄μ˜ ν•œ μΉΈ μ™Όμͺ½μ— μžˆλ‹€. λ‹€μŒμ€ 1초 λ™μ•ˆ μΌμ–΄λ‚˜λŠ” 일이며, μ•„λž˜ 적힌 μˆœμ„œλŒ€λ‘œ μΌμ–΄λ‚œλ‹€. λ‚šμ‹œμ™•μ€ κ°€μž₯ 였λ₯Έμͺ½ μ—΄μ˜ 였λ₯Έμͺ½ 칸에 μ΄λ™ν•˜λ©΄ μ΄λ™μ„ λ©ˆμΆ˜λ‹€.

  1. λ‚šμ‹œμ™•μ΄ 였λ₯Έμͺ½μœΌλ‘œ ν•œ μΉΈ μ΄λ™ν•œλ‹€.
  2. λ‚šμ‹œμ™•μ΄ μžˆλŠ” 열에 μžˆλŠ” 상어 μ€‘μ—μ„œ λ•…κ³Ό 제일 κ°€κΉŒμš΄ 상어λ₯Ό μž‘λŠ”λ‹€. 상어λ₯Ό 작으면 κ²©μžνŒμ—μ„œ μž‘μ€ 상어가 사라진닀.
  3. 상어가 μ΄λ™ν•œλ‹€.

μƒμ–΄λŠ” μž…λ ₯으둜 μ£Όμ–΄μ§„ μ†λ„λ‘œ μ΄λ™ν•˜κ³ , μ†λ„μ˜ λ‹¨μœ„λŠ” μΉΈ/μ΄ˆμ΄λ‹€. 상어가 μ΄λ™ν•˜λ €κ³  ν•˜λŠ” 칸이 격자판의 경계λ₯Ό λ„˜λŠ” κ²½μš°μ—λŠ” λ°©ν–₯을 λ°˜λŒ€λ‘œ λ°”κΏ”μ„œ 속λ ₯을 μœ μ§€ν•œμ±„λ‘œ μ΄λ™ν•œλ‹€.

μ™Όμͺ½ 그림의 μƒνƒœμ—μ„œ 1μ΄ˆκ°€ μ§€λ‚˜λ©΄ 였λ₯Έμͺ½ μƒνƒœκ°€ λœλ‹€. 상어가 보고 μžˆλŠ” λ°©ν–₯이 μ†λ„μ˜ λ°©ν–₯, μ™Όμͺ½ μ•„λž˜μ— 적힌 μ •μˆ˜λŠ” 속λ ₯이닀. μ™Όμͺ½ μœ„μ— 상어λ₯Ό κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ 문자λ₯Ό μ μ—ˆλ‹€.

상어가 이동을 마친 후에 ν•œ 칸에 상어가 두 마리 이상 μžˆμ„ 수 μžˆλ‹€. μ΄λ•ŒλŠ” 크기가 κ°€μž₯ 큰 상어가 λ‚˜λ¨Έμ§€ 상어λ₯Ό λͺ¨λ‘ μž‘μ•„λ¨ΉλŠ”λ‹€.

λ‚šμ‹œμ™•μ΄ 상어 λ‚šμ‹œλ₯Ό ν•˜λŠ” 격자판의 μƒνƒœκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, λ‚šμ‹œμ™•μ΄ μž‘μ€ μƒμ–΄ 크기의 합을 κ΅¬ν•΄λ³΄μž.

μž…λ ₯

첫째 쀄에 격자판의 크기 R, C와 μƒμ–΄μ˜ 수 M이 μ£Όμ–΄μ§„λ‹€. (2 ≤ R, C ≤ 100, 0 ≤ M ≤ R×C)

λ‘˜μ§Έ 쀄뢀터 M개의 쀄에 μƒμ–΄μ˜ 정보가 μ£Όμ–΄μ§„λ‹€. μƒμ–΄μ˜ μ •λ³΄λŠ” λ‹€μ„― μ •μˆ˜ r, c, s, d, z (1 ≤ r ≤ R, 1 ≤ c ≤ C, 0 ≤ s ≤ 1000, 1 ≤ d ≤ 4, 1 ≤ z ≤ 10000) λ‘œ 이루어져 μžˆλ‹€. (r, c)λŠ” μƒμ–΄μ˜ μœ„μΉ˜, sλŠ” 속λ ₯, dλŠ” 이동 λ°©ν–₯, zλŠ” 크기이닀. dκ°€ 1인 κ²½μš°λŠ” μœ„, 2인 κ²½μš°λŠ” μ•„λž˜, 3인 κ²½μš°λŠ” 였λ₯Έμͺ½, 4인 κ²½μš°λŠ” μ™Όμͺ½μ„ μ˜λ―Έν•œλ‹€.

두 상어가 같은 크기λ₯Ό κ°–λŠ” κ²½μš°λŠ” μ—†κ³ , ν•˜λ‚˜μ˜ 칸에 λ‘˜ μ΄μƒμ˜ 상어가 μžˆλŠ” κ²½μš°λŠ” μ—†λ‹€.

좜λ ₯

λ‚šμ‹œμ™•μ΄ μž‘μ€ 상어 크기의 합을 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1 λ³΅μ‚¬

4 6 8
4 1 3 3 8
1 3 5 2 9
2 4 8 4 1
4 5 0 1 4
3 3 1 2 7
1 5 8 4 3
3 6 2 1 2
2 2 2 3 5

예제 좜λ ₯ 1 λ³΅μ‚¬

22

각 칸의 μ™Όμͺ½ μ•„λž˜μ— 적힌 μˆ˜λŠ” 속λ ₯, 였λ₯Έμͺ½ μ•„λž˜λŠ” 크기, μ™Όμͺ½ μœ„λŠ” 상어λ₯Ό κ΅¬λΆ„ν•˜κΈ° μœ„ν•œ λ¬Έμžμ΄λ‹€. 였λ₯Έμͺ½ μœ„μ— β€οΈλŠ” λ‚šμ‹œμ™•μ΄ μž‘μ€ λ¬Όκ³ κΈ° ν‘œμ‹œμ΄λ‹€.

초기 μƒνƒœ

1초

2초 (E번 μƒμ–΄λŠ” Bλ²ˆμ—κ²Œ λ¨Ήν˜”λ‹€)

3초

4초

5초

6초

 

풀이

 

λΉ‘κ΅¬ν˜„μ‹œν‚€λ©΄μ„œ μ‹œκ°„μ΄ˆκ³Ό μœ λ„ν•˜λŠ” λ¬Έμ œμ΄λ‹€.

 

ν’€μ΄μžμ²΄λŠ” κ°„λ‹¨ν•˜λ‹€. κ·Έλƒ₯ λ¬Έμ œμ—μ„œ μ„€λͺ…ν•˜λŠ” λŒ€λ‘œ μ­‰ 짜주면 λœλ‹€.

λ‹€λ§Œ μž…λ ₯ λ°°μ—΄μ˜ μ‚¬μ΄μ¦ˆκ°€ 100 * 100이고, μƒμ–΄μ˜ 속λ ₯이 1000이라 상어λ₯Ό μ΄λ™μ‹œν‚¬λ•Œ 상어가 λͺ¨λ“ μΉΈμ— μžˆλ‹€λŠ” κ°€μ • ν•˜μ—

μƒμ–΄μ˜ 개수 * μ—΄ * μƒμ–΄μ˜ 속λ ₯으둜 N*M^2*SλΌλŠ” κ΄΄λž„ν•œ μ‹œκ°„μ΄ λ‚˜μ˜€κ²Œ λœλ‹€.

κ·ΈλŸ¬λ―€λ‘œ 상어λ₯Ό μ΄λ™ν•˜λŠ” λ™μž‘μ—μ„œ μ΅œλŒ€ν•œ μ‹œκ°„μ„ λΉΌμ£Όμ–΄μ•Ό ν•œλ‹€.

 

void move_shark(){
    vector<shark>move[102][102];
    vector<pair<int,int>>si;
    int vis[102][102] = {0};
        for(auto point : sh_point){
            if(board[point.first][point.second].empty()) continue;
            shark cur = board[point.first][point.second][0];
            int curx = point.first, cury = point.second;
            board[point.first][point.second].pop_back();
            int ns = cur.s;
            //for(int k=0; k<board[point.first][point.second][0].s; k++){ 
            while(ns){
                int s;
                if(cur.d == 1)
                    s = curx-1;
                else if(cur.d == 2)
                    s = R-curx;
                else if(cur.d == 3)
                    s = C-cury;
                else if(cur.d == 4)
                    s = cury-1;
                if(ns < s)
                    s = ns;
                ns -= s;
                int nx = curx + dx[cur.d-1]*s;
                int ny = cury + dy[cur.d-1]*s;
                // if((nx == 0 || nx == R || ny == 0 || ny == C)){
                //     if(cur.d == 1)
                //         cur.d = 2;
                //     else if(cur.d == 2)
                //         cur.d = 1;
                //     if(cur.d == 3)
                //         cur.d = 4;
                //     else if(cur.d == 4)
                //         cur.d = 3;
                // }
                if((nx == 1 || nx == R) &&(cur.d == 1 || cur.d ==2)){
                    if(cur.d == 1)
                        cur.d = 2;
                    else if(cur.d == 2)
                        cur.d = 1;
                }else if((ny == 1 || ny == C) && (cur.d == 3 || cur.d == 4) ){
                    if(cur.d == 3)
                        cur.d = 4;
                    else if(cur.d == 4)
                        cur.d = 3;
                }
                curx = nx;
                cury = ny;
            }
            
             
            if(move[curx][cury].empty())
                move[curx][cury].push_back(cur);
            else{
                shark com = move[curx][cury][0];
                move[curx][cury].pop_back();
                if(com.z > cur.z)
                    move[curx][cury].push_back(com);
                else
                    move[curx][cury].push_back(cur);
            }
            if(vis[curx][cury] == 0){
                vis[curx][cury] = 1;
                si.push_back({curx,cury});
            }
        }
        for(auto e : si){
            if(move[e.first][e.second].empty()) continue;
            board[e.first][e.second].push_back(move[e.first][e.second][0]);
        }
    sh_point = si;
    return;
}

 

이 뢀뢄이 상어λ₯Ό 움직이고, λ¨ΉλŠ” κ³Όμ •κΉŒμ§€ ν•œ μ½”λ“œμ΄λ‹€.

μ—¬κΈ°μ„œ μ€‘μš”ν•œ 뢀뢄은

 

while(ns){
                int s;
                if(cur.d == 1)
                    s = curx-1;
                else if(cur.d == 2)
                    s = R-curx;
                else if(cur.d == 3)
                    s = C-cury;
                else if(cur.d == 4)
                    s = cury-1;
                if(ns < s)
                    s = ns;
                ns -= s;
                int nx = curx + dx[cur.d-1]*s;
                int ny = cury + dy[cur.d-1]*s;
                // if((nx == 0 || nx == R || ny == 0 || ny == C)){
                //     if(cur.d == 1)
                //         cur.d = 2;
                //     else if(cur.d == 2)
                //         cur.d = 1;
                //     if(cur.d == 3)
                //         cur.d = 4;
                //     else if(cur.d == 4)
                //         cur.d = 3;
                // }
                if((nx == 1 || nx == R) &&(cur.d == 1 || cur.d ==2)){
                    if(cur.d == 1)
                        cur.d = 2;
                    else if(cur.d == 2)
                        cur.d = 1;
                }else if((ny == 1 || ny == C) && (cur.d == 3 || cur.d == 4) ){
                    if(cur.d == 3)
                        cur.d = 4;
                    else if(cur.d == 4)
                        cur.d = 3;
                }
                curx = nx;
                cury = ny;
            }

이 상어λ₯Ό μ›€μ§μ΄λŠ” 뢀뢄이닀.

상어가 λ°©ν–₯을 λ°”κΎΈλŠ” ꡬ간은 0번째, R번째 행에 μžˆμ„λ•Œ. 0번째, C번째 열에 μžˆλŠ” κ²½μš°μ΄λ‹€.

κ·ΈλŸ¬λ―€λ‘œ 상어가 3λ²ˆν–‰μ— μžˆλ‹€ κ°€μ •ν•˜κ³  R == 7이라 κ°€μ •ν•˜μž.

상어가 λ°©ν–₯이 λ°”λ€Œμ§€ μ•Šκ³  μœ„λ‘œ μ›€μ§μ΄λŠ” κ²½μš°λŠ” μ΅œλŒ€ 3(μƒμ–΄μ˜ ν–‰μ˜ μœ„μΉ˜κ°’) 만큼 움직일 수 μžˆλ‹€.

상어가 λ°©ν–₯이 λ°”λ€Œμ§€ μ•Šκ³  μ•„λž˜λ‘œ μ›€μ§μ΄λŠ” κ²½μš°λŠ” μ΅œλŒ€ 4(R - μƒμ–΄μ˜ ν–‰μ˜ μœ„μΉ˜κ°’) 만큼 움직일 수 μžˆλ‹€.

이λ₯Ό μ΄μš©ν•΄μ„œ 상어λ₯Ό ν•œλ²ˆ μ›€μ§μΌλ•Œ μ΅œλŒ€ν•œ 많이 움직여주면 λœλ‹€.

 

포인트

상어가 0λ²ˆμ΄λ‚˜ κ°€μž₯μžλ¦¬μ— μžˆλŠ” κ²½μš°μ—λŠ”, λ°©ν–₯이 계속 λ°”λ€Œμ–΄λ„ λœλ‹€.

λ¬Όλ‘  μ•½κ°„μ˜ μ‹œκ°„μ΄ 더 λ“€ μˆ˜λŠ” μžˆμ§€λ§Œ, λ°©ν–₯이 λ°˜λŒ€μ—¬λ„ μ–΄μ²˜ν”Ό 1초 ν›„μ˜ λ°©ν–₯κ³Ό μœ„μΉ˜λŠ” κ°™κΈ° λ•Œλ¬Έμ΄λ‹€.

 

전체 μ½”λ“œ

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int R,C,M,dx[4]={-1,1,0,0},dy[4]={0,0,1,-1}, ans;
struct shark{
    int s,d,z=0;
};
vector<pair<int,int>>sh_point;
vector<shark>board[102][102];
void catch_shark(int idx){
    for(int i=1; i<=R; i++){
        if(board[i][idx].empty()) continue;
        ans += board[i][idx][0].z;
        board[i][idx].pop_back();
        return;
    }
}
void move_shark(){
    vector<shark>move[102][102];
    vector<pair<int,int>>si;
    int vis[102][102] = {0};
        for(auto point : sh_point){
            if(board[point.first][point.second].empty()) continue;
            shark cur = board[point.first][point.second][0];
            int curx = point.first, cury = point.second;
            board[point.first][point.second].pop_back();
            int ns = cur.s;
            //for(int k=0; k<board[point.first][point.second][0].s; k++){ 
            while(ns){
                int s;
                if(cur.d == 1)
                    s = curx-1;
                else if(cur.d == 2)
                    s = R-curx;
                else if(cur.d == 3)
                    s = C-cury;
                else if(cur.d == 4)
                    s = cury-1;
                if(ns < s)
                    s = ns;
                ns -= s;
                int nx = curx + dx[cur.d-1]*s;
                int ny = cury + dy[cur.d-1]*s;
                // if((nx == 0 || nx == R || ny == 0 || ny == C)){
                //     if(cur.d == 1)
                //         cur.d = 2;
                //     else if(cur.d == 2)
                //         cur.d = 1;
                //     if(cur.d == 3)
                //         cur.d = 4;
                //     else if(cur.d == 4)
                //         cur.d = 3;
                // }
                if((nx == 1 || nx == R) &&(cur.d == 1 || cur.d ==2)){
                    if(cur.d == 1)
                        cur.d = 2;
                    else if(cur.d == 2)
                        cur.d = 1;
                }else if((ny == 1 || ny == C) && (cur.d == 3 || cur.d == 4) ){
                    if(cur.d == 3)
                        cur.d = 4;
                    else if(cur.d == 4)
                        cur.d = 3;
                }
                curx = nx;
                cury = ny;
            }
            
             
            if(move[curx][cury].empty())
                move[curx][cury].push_back(cur);
            else{
                shark com = move[curx][cury][0];
                move[curx][cury].pop_back();
                if(com.z > cur.z)
                    move[curx][cury].push_back(com);
                else
                    move[curx][cury].push_back(cur);
            }
            if(vis[curx][cury] == 0){
                vis[curx][cury] = 1;
                si.push_back({curx,cury});
            }
        }
        for(auto e : si){
            if(move[e.first][e.second].empty()) continue;
            board[e.first][e.second].push_back(move[e.first][e.second][0]);
        }
    sh_point = si;
    return;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin>>R>>C>>M;
    //input
    for(int i=0; i<M; i++){
        shark ns;
        int x, y;
        cin>>x>>y>>ns.s>>ns.d>>ns.z;
        board[x][y].push_back(ns);
        sh_point.push_back({x,y});
    }
    for(int st=1; st<=C; st++){
        catch_shark(st);
        move_shark();
    }
    cout<<ans;
}