-
[백준] 어른상어Study/Coding Test 2021. 10. 17. 23:11
https://www.acmicpc.net/problem/19237
19237번: 어른 상어
첫 줄에는 N, M, k가 주어진다. (2 ≤ N ≤ 20, 2 ≤ M ≤ N2, 1 ≤ k ≤ 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미
www.acmicpc.net
마지막에 answer >= 1000 조건에서 = 조건 안넣어서 틀림....
#define _CRT_SECURE_NO_DEPRECATE #include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> using namespace std; int answer; int N, M, k; struct Shark { int row; int col; int num; int dir; }; vector< vector<int> > board[21][21]; //{num, 냄새} vector<Shark> sharkes; vector<int> priorities[5][401]; //row: 방향, col : 상어번호 int dr[5] = { 0,-1,1,0,0 }; int dc[5] = { 0,0,0,-1,1 }; void init() { for (int i = 0; i < 21; i++) { for (int j = 0; j < 21; j++) { board[i][j] = {}; } } sharkes = {}; for (int i = 0; i < 5; i++) { for (int j = 0; j < 401; j++) { priorities[i][j] = {}; } } } bool comp(Shark s1, Shark s2) { return s1.num < s2.num; } bool comp2(vector<int> v1, vector<int> v2) { if (v1[0] == v2[0]) { return v1[1] > v2[1]; } else { return v1[0] < v2[0]; } } void input() { cin >> N >> M >> k; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int num; cin >> num; if (num > 0) { //상어 board[i][j] = {{num, k}}; sharkes.push_back({ i,j,num,0 }); } } } sort(sharkes.begin(), sharkes.end(), comp); for (int i = 0; i < M; i++) { int d; cin >> d; sharkes[i].dir = d; } //우선순위 for (int i = 1; i <= M; i++) { for (int j = 1; j <= 4; j++) { int p; vector<int> temp; for (int k = 0; k < 4; k++) { cin >> p; temp.push_back(p); } priorities[j][i] = temp; } } } void print() { cout << "상어 위치" << endl; for (int i = 0; i < sharkes.size(); i++) { cout << i << " : " << sharkes[i].row << " " << sharkes[i].col << " " << sharkes[i].num << " " << sharkes[i].dir << endl; } cout << endl; cout << "냄새" << endl; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < board[i][j].size(); k++) { cout << i << " " << j << " : " << board[i][j][k][0] << " " << board[i][j][k][1] << endl; } } } cout << endl; cout << " ----------------------- " << endl; } bool inRange(int r, int c) { return r >= 0 && r < N&& c >= 0 && c < N; } int decideDir(int row, int col, int num, int dir) { vector< vector<int> > candidate1; // 냄새없는 경우 vector< vector<int> > candidate2; // 자신의 냄새가 있는 경우 // 후보 찾기. for (int i = 1; i <= 4; i++) { int nr = row + dr[i]; int nc = col + dc[i]; if (inRange(nr, nc)) { if (board[nr][nc].size() == 0) { candidate1.push_back({ nr,nc,i }); } else { for (int j = 0; j < board[nr][nc].size(); j++) { if (board[nr][nc][j][0] == num) { candidate2.push_back({ nr,nc,i }); } } } } } if (candidate1.size() > 0) { //냄새가 없는 칸이 있는 경우. for (int p = 0; p < 4; p++) { //priorities[d][n] int nd = priorities[dir][num][p]; for (int i = 0; i < candidate1.size(); i++) { if (candidate1[i][2] == nd) { return nd; } } } } else if (candidate2.size() > 0){ //자신의 냄새가 있는 경우 for (int p = 0; p < 4; p++) { //priorities[d][n] int nd = priorities[dir][num][p]; for (int i = 0; i < candidate2.size(); i++) { if (candidate2[i][2] == nd) { return nd; } } } } else { for (int p = 0; p < 4; p++) { //priorities[d][n] int nd = priorities[dir][num][p]; int nr = row + dr[nd]; int nc = col + dc[nd]; if (inRange(nr, nc)) { return nd; } } } } void moveShark(vector<vector<int>> &s) { for (int i = 0; i < s.size(); i++) { int idx = s[i][0]; int row = s[i][1]; int col = s[i][2]; int num = s[i][3]; int nd = s[i][4]; int nr = row + dr[nd]; int nc = col + dc[nd]; //상어 이동 sharkes[idx] = { nr,nc,num,nd }; //이동한 위치 냄새 추가 board[nr][nc].push_back({ num, k }); } } void deleteShark() { for (int r = 0; r < N; r++) { for (int c = 0; c < N; c++) { if (board[r][c].size() > 1) { sort(board[r][c].begin(), board[r][c].end(), comp2); int target = board[r][c][0][0]; vector<int> temp = board[r][c][0]; board[r][c].clear(); board[r][c].push_back(temp); vector<Shark>::iterator iter; for (iter = sharkes.begin(); iter != sharkes.end();) { Shark s = *iter; if (s.row == r && s.col == c && s.num != target) { iter = sharkes.erase(iter); } else { iter++; } } } } } } bool check() { if (sharkes.size() == 1) { return false; } for (int i = 0; i < sharkes.size(); i++) { if (sharkes[i].num == 1) { return true; } } return false; } void solve() { while (check()) { if (answer >= 1000) { answer = -1; return; } //냄새 줄이기. for (int r = 0; r < N; r++) { for (int c = 0; c < N; c++) { if (board[r][c].size() > 0) { vector<int> v = board[r][c][0]; if (v[1] > 0) { board[r][c][0][1]--; } else if (v[1] == 0) { board[r][c] = {}; } } } } //이동할 상어 저장 vector<vector<int>> temp_shark; for (int i = 0; i < sharkes.size(); i++) { int r = sharkes[i].row; int c = sharkes[i].col; int n = sharkes[i].num; int d = sharkes[i].dir; //이동방향 결정 int nd = decideDir(r, c, n, d); //상어 이동 temp_shark.push_back({ i,r,c,n,nd }); } moveShark(temp_shark); //한 칸에 여러마리의 상어가 남아있으면 제거. deleteShark(); //print(); answer++; } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("input.txt", "r", stdin); //init(); input(); solve(); cout << answer << endl; return 0; }
'Study > Coding Test' 카테고리의 다른 글
[백준] 사다리 조작 (0) 2021.10.21 [백준] 모노미노도미노2 (0) 2021.10.19 [백준] 마법사 상어와 파이어볼 (0) 2021.10.17 [백준] 컨베이어 벨트 위의 로봇 (0) 2021.10.16 [백준] 마법사 상어와 파이어스톰 (0) 2021.10.15