๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“ ์•Œ๊ณ ๋ฆฌ์ฆ˜/Softeer

[C++/Softeer] Lv3. ํ•จ๊ป˜ํ•˜๋Š” ํšจ๋„

https://softeer.ai/practice/7727

 

Softeer - ํ˜„๋Œ€์ž๋™์ฐจ๊ทธ๋ฃน SW์ธ์žฌํ™•๋ณดํ”Œ๋žซํผ

 

softeer.ai

 

ํ˜„๋Œ€ ์†Œํ”„ํ‹ฐ์–ด Lv3. ํ•จ๊ป˜ํ•˜๋Š” ํšจ๋„ C++ ํ’€์ด

 

๊ฝค๋‚˜ ๊นŒ๋‹ค๋กœ์› ๋˜ ๋ฌธ์ œ์ด๋‹ค.

์ฝ”ํ…Œ ๊ณต๋ถ€๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฉด์„œ ์ฒ˜์Œ์œผ๋กœ ํ‘ผ ๋ฌธ์ œ์ธ๋ฐ,

์—ด์‹ฌํžˆ ๊ณ ๋ฏผํ•˜๋ฉด์„œ ํ’€๋‹ค๋ณด๋‹ˆ ์˜ˆ์ „ ์‹ค๋ ฅ์ด ๊ธˆ๋ฐฉ ๋Œ์•„์˜จ ๋Š๋‚Œ์ด๋‹ค


1. ์ดˆ์•ˆ(ํ…Œ์ผ€๋งŒ ๋งž์Œ)

  1. ์บ๋ฆญํ„ฐ ๊ทผ์ฒ˜์˜ 4๋ฐฉํ–ฅ ํƒ์ƒ‰ ํ›„, max๊ฐ’์œผ๋กœ ์ด๋™ → 3์ดˆ ํ›„ ์ •์ง€ํ•˜๋„๋ก ํ•จ
  2. ๊ทผ๋ฐ ์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•์ด์—ˆ์Œ!!! 3๋ฒˆ ์ด๋™ํ•˜๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ , ๊ทธ ์ค‘ max๊ฐ’์„ ์–ป๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ฆฌํ„ดํ•ด์•ผํ•จ
  3. grid ๋ณต์‚ฌํ•ด์„œ ์—ฌ๋Ÿฌ๋ช… ์ง€๋‚˜๊ฐ€๋Š” ๋ฃจํŠธ ์ฒดํฌ, visited๋กœ ํ•œ๋ช… ์ง€๋‚˜๊ฐ€๋Š” ๋ฃจํŠธ ์ฒดํฌ

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋น„๊ต์  ์‰ฌ์šด bfs๋กœ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•œ ์ดˆ์•ˆ์ž…๋‹ˆ๋‹ค....ํ…Œ์ผ€๋Š” ๋งž์•˜์ง€๋งŒ ์ œ์ถœํ•ด๋ณด๋‹ˆ ์‹คํŒจ.

์ˆ˜์ •ํ•˜๋‹ค๊ฐ€ dfs๋กœ ํ’€์–ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์ฃ 

 

int findMax(int X, int Y, int grid[20][20]){
    int x = X-1;
    int y = Y-1;
    queue<pair<int,int>> q;
    int fruit = grid[x][y];
    int nx=0; int ny=0; int maxtree = 0;
    int cnt = 0;
    grid[x][y] = 0; // ํ˜„์žฌ ์œ„์น˜๋„ ์—ด๋งค ๋”ฐ์•ผํ•จ
    q.push({x,y});

    while(cnt < 3){
        pair<int,int> p = q.front();
        q.pop();
        maxtree = 0;
        for(int i=0; i<4; ++i){
            int mx = p.first + move_x[i];
            int my = p.second + move_y[i];
            if(canMove(mx,my) && (maxtree < grid[mx][my])){
                maxtree = grid[mx][my];
                nx = mx; ny = my;
            }
        }
        q.push({nx,ny});
        fruit += maxtree;
        grid[nx][ny] = 0;
        cnt ++;
    }
    return fruit;
}

 

 

์™œ dfs๋กœ ํ•ด์•ผํ•˜๋‚˜?

-> ๊นŠ์ด ์šฐ์„ ์œผ๋กœ 3์ดˆ๋™์•ˆ ๋๊นŒ์ง€ ์›€์ง์ด๋Š” ๋ชจ๋“  ๋ฃจํŠธ๋ฅผ ํƒ์ƒ‰ํ•ด์•ผํ•จ!

3์ดˆ๋™์•ˆ ์ฒซ๋ฒˆ์งธ ๋ฃจํŠธ์—์„œ ๋”ธ ์ˆ˜ ์žˆ๋Š” ์—ด๋งค์˜ sum์„ ๊ตฌํ•˜๊ณ ,

๋‹ค์‹œ ์ถœ๋ฐœ์ ์œผ๋กœ ๋Œ์•„์™€์„œ

๋‘๋ฒˆ์งธ ๋ฃจํŠธ์—์„œ ๋”ธ ์ˆ˜ ์žˆ๋Š” ์—ด๋งค์˜ sum์„ ๊ตฌํ•˜๊ณ ,

... ๋ฐ˜๋ณต

 

๊ทธ๋ฆฌ๊ณ  ์นœ๊ตฌ 1, ์นœ๊ตฌ2๊ฐ€ ์žˆ์„๋•Œ ์ˆœ์—ด๋กœ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ”์„œ ๋ฐ˜๋ณตํ•˜๋Š”๊ฒƒ ๊นŒ์ง€๋Š” ์บ์น˜ํ–ˆ๋Š”๋ฐ

๊ฐ ์นœ๊ตฌ์˜ ์—ด๋งค max๋ฅผ ๊ตฌํ•˜๊ณ 

๊ทธ max ๊ฒฝ๋กœ๋งŒ ์ €์žฅํ•ด์„œ ์—ด๋งค ์ˆ˜๋ฅผ 0์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ์Œ! (์ด๋ฏธ ์—ด๋งค๋ฅผ ๋”ด ๋‚˜๋ฌด)

์ฒ˜์Œ ๋ดค์„ ๋• ์‰ฌ์›Œ๋ณด์ด๋Š” ๋ฌธ์ œ์˜€๋Š”๋ฐ, ๊ตฌํ˜„์ด ์ƒ๊ฐ๋ณด๋‹ค ๋นก์…Œ๋‹ค

 

2. ํ’€์ด

dfs์—์„œ current_fruit ์ „๋‹ฌํ•˜๊ณ , max fruit์ด ๊ฐฑ์‹ ๋  ๋•Œ๋งŒ bestPath๋ฅผ ์ €์žฅํ–ˆ๋Š”๋ฐ ๋ญ”๊ฐ€ ์ด์ƒํ•ด์„œ ์ถœ๋ ฅํ•ด๋ณด๋‹ˆ

์ง€์—ญ๋ณ€์ˆ˜ ๋น„๊ต๊ฐ€ ์ž˜๋ชป๋˜๊ณ  ์žˆ๋Š”์ง€ ๊ทธ๋ƒฅ ๋Œ๋ฆฌ๋Š” ์กฑ์กฑ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฐ’์ด ๊ฐฑ์‹ ๋˜๊ธธ๋ž˜

fruit ์ตœ๋Œ“๊ฐ’์ด ๋‚˜์˜ฌ ๋•Œ๋งˆ๋‹ค ์ „์—ญ๋ณ€์ˆ˜ ๋ฒกํ„ฐ์— ํ‘ธ์‹œํ•ด์„œ, vector.back() ๊ฐ’์„ ๋น„๊ตํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

→ max์ผ๋•Œ์˜ ๊ฒฝ๋กœ๊ฐ€ ์ž˜ ์ €์žฅ๋จ. ์ „์—ญ ๋ฒกํ„ฐ๊ฐ€ ๋‹ต์ด์—ˆ๋‹ค…………

 

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

int grid[20][20] = {0,};
int tmp[20][20] = {0,};
bool visited[20][20] = {false,};
bool route[20][20] = {false,};
int n; int m;
int move_x[4] = {0,1,0,-1};
int move_y[4] = {1,0,-1,0};
vector<pair<int, int>> bestPath;
vector<pair<int, int>> currentPath;
vector<int> results;

bool canMove(int nx, int ny){
    if(nx<0 || nx>=n || ny<0 || ny>=n) return false;
    return true;
}

int dfs(int x, int y, int time, int current_fruit) {
    if (time >= 3) {
        return current_fruit;
    }
    int max_fruit = current_fruit;
    for (int i = 0; i < 4; ++i) {
        int mx = x + move_x[i];
        int my = y + move_y[i];
        if (canMove(mx, my) && !visited[mx][my]) {
            int fruit = grid[mx][my];
            visited[mx][my] = true;
            currentPath.push_back({mx, my});
            int total_fruit = dfs(mx, my, time + 1, current_fruit + fruit);
            if (results.back() < total_fruit) {
                results.push_back(total_fruit); // ์ด๊ฑฐ์˜€์Œ!!!!!!!!!
                max_fruit = total_fruit;
                if (time == 2) {
                    bestPath = currentPath;
                    // cout << max_fruit<<"/";
                    // for(auto i:bestPath) cout << i.first<<","<<i.second<<"\n";
                }
            }
            currentPath.pop_back();
            visited[mx][my] = false;
        }
    }
    return results.back();
}

int findMax(int x, int y){
    // cout << x<<","<<y<<")\n";
    int start_fruit = grid[x][y];
    visited[x][y] = 1;
    grid[x][y] = 0;
    results.push_back(start_fruit);
    int max_fruit = dfs(x, y, 0, start_fruit);
    visited[x][y] = 0;
    
    for(auto i:bestPath){
        // cout <<"("<< i.first<<"," << i.second<<") ";
        grid[i.first][i.second] = 0;
    }
    currentPath.clear();
    return max_fruit;
}

int main(int argc, char** argv)
{
    int friends[3][3] = {0,};
    int answer = 0;
    cin >> n >> m;
    for(int i=0; i<n; ++i){
        for(int j=0; j<n; ++j) {
            cin >> grid[i][j];
        }
    }
    for(int i=0; i<m; ++i) cin >> friends[i][0] >> friends[i][1];
    memcpy(tmp, grid, sizeof(grid));
    vector<int> mlist;
    for(int i=0; i<m; ++i) mlist.push_back(i);
    do {
        int max = 0;
        memcpy(grid, tmp, sizeof(tmp));
        for (int j = 0; j < m; ++j) {
            int fr = mlist[j];
            max += findMax(friends[fr][0]-1, friends[fr][1]-1);
            // cout << max << "///----\n\n";
        }
        if (answer < max) answer = max;
    } while (next_permutation(mlist.begin(), mlist.end())); // ์ž˜๋ชป๋œ ๊ณต๋ฐฑ ๋ฌธ์ž ์ˆ˜์ •
    cout << answer;
   return 0;
}

 

 

ํœด ์˜ค๋žœ๋งŒ์— n์‹œ๊ฐ„ ์ˆœ์‚ญ~~