거의 알고리즘 일기장

백준 16988번 _ Baaaaaaaaaduk2 (Easy) 본문

알고리즘 문제풀이

백준 16988번 _ Baaaaaaaaaduk2 (Easy)

건우권 2020. 10. 12. 00:02

www.acmicpc.net/problem/16988

 

16988번: Baaaaaaaaaduk2 (Easy)

서기 2116년, 인간은 더 이상 AI의 상대가 되지 못하게 되었다. 근력, 순발력, 창의력, 사고력, 문제해결능력, 심지어 인간미조차 AI가 인간을 앞선다. AI가 온 지구를 관리하며 이미 인류는 지구의

www.acmicpc.net


코드

/*
풀이방법 
1. 돌의 집합 vector를 미리 만들어서 거기에 집합 주변의 빈좌표들을 넣어줍니다.
2. 조합을 돌리면서 board에 돌을 두개 놓고 몇마리가 잡혔는지 위에 만들었던 돌의 집합 vector를 순회하며 확인합니다.

아까 코드는 좀 이상하게 짜놔서 조금 고쳤습니다.
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>

using namespace std;

int N, M;
vector<pair<int, int>> possiblePlace;
int board[20][20];
int dy[4] = { -1, 1, 0, 0 };
int dx[4] = { 0, 0, -1, 1 };
bool visit[20][20];

bool IsInRange(int y, int x)
{
    if (y >= 0 && y < N && x >= 0 && x < M)
        return true;
    return false;
}

void Input()
{
    cin >> N >> M;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            int val;
            cin >> val;
            board[i][j] = val;

            if (val == 0)
                possiblePlace.push_back({ i, j });
        }
    }
}

void printBoard()
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            cout << board[i][j] << ' ';
        }
        cout << '\n';
    }
}

void setStoneInBoard(const vector<pair<int, int>> & stonePutPlace)
{
    for (auto pos : stonePutPlace)
        board[pos.first][pos.second] = 1;
}

void returnStoneInBoard(const vector<pair<int, int>> & stonePutPlace)
{
    for (auto pos : stonePutPlace)
        board[pos.first][pos.second] = 0;
}

bool compare(const pair<int, int> & a, const pair<int, int> & b)
{
    if (a.first == b.first)
        return a.second < b.second;
    return a.first < b.first;
}

int getKillNumber(const vector<pair<vector<pair<int, int>>, int>> & candidate)
{
    int ret = 0;

    for (int i =0; i<candidate.size(); i++)
    {
        auto candidatePos = candidate[i].first;
        int size = candidate[i].second;

        bool isPossible = true;
        for (int j = 0; j < candidatePos.size(); j++)
        {
            if (board[candidatePos[j].first][candidatePos[j].second] != 1)
                isPossible = false;
        }

        if (isPossible == true)
            ret += size;
    }

    return ret;
}

void solve(const vector<pair<vector<pair<int, int>>, int>> & candidate)
{
    int answer = 0;

    //1. 두개를 골라서 둔다.
    vector<int> temp;
    temp.resize(possiblePlace.size());
    for (int i = 0; i < 2; i++)
        temp[i] = 1;
    sort(begin(temp), end(temp));

    do
    {
        vector<pair<int, int>> stonePutPlace;
        for (int i = 0; i < temp.size(); i++)
        {
            if (temp[i] == 1)
                stonePutPlace.push_back(possiblePlace[i]);
        }
        //확인
        setStoneInBoard(stonePutPlace);
        answer = max(answer, getKillNumber(candidate));
        returnStoneInBoard(stonePutPlace);

    } while (next_permutation(begin(temp), end(temp)));

    cout << answer << '\n';
}

void dfs(int y, int x, set<pair<int, int>> & v, set<pair<int, int>> & s)
{
    if (IsInRange(y, x) == false)
        return;
    if (visit[y][x] == true)
        return;

    if (board[y][x] == 1)
        return;

    if (board[y][x] == 0)
    {
        v.insert({ y, x });
        return;
    }

    visit[y][x] = true;
    s.insert({ y, x });

    for (int i = 0; i < 4; i++)
    {
        int ny = y + dy[i];
        int nx = x + dx[i];

        dfs(ny, nx, v, s);
    }
}

int main()
{
    Input();

    int answer = 0;

    vector<pair<vector<pair<int, int>>, int>>candidate;
    set<pair<int, int>> v;
    set<pair<int, int>> s;
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (visit[i][j] == true)
                continue;

            v.clear();
            s.clear();
            dfs(i, j, v, s);

            if (v.size() > 2)
                continue;

            if (s.size() == 0)
                continue;

            vector<pair<int, int>> temp;
            for (auto ele : v)
                temp.push_back(ele);

            candidate.push_back({ temp, s.size() });
        }
    }
    solve(candidate);

    return 0;
}
반응형

'알고리즘 문제풀이' 카테고리의 다른 글

백준 17472번 _ 다리 만들기 2  (0) 2020.10.12
백준 5213번 _ 과외맨  (0) 2020.10.12
백준 17406번 _ 배열 돌리기 4  (0) 2020.10.12
백준 1400번 _ 화물차  (0) 2020.10.11
백준 19236번 _ 청소년 상어  (0) 2020.10.11
Comments