-
[백준] 상어 초등학교Study/Coding Test 2021. 10. 15. 14:17
https://www.acmicpc.net/problem/21608
21608번: 상어 초등학교
상어 초등학교에는 교실이 하나 있고, 교실은 N×N 크기의 격자로 나타낼 수 있다. 학교에 다니는 학생의 수는 N2명이다. 오늘은 모든 학생의 자리를 정하는 날이다. 학생은 1번부터 N2번까지 번호
www.acmicpc.net
#define _CRT_SECURE_NO_DEPRECATE #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <cmath> using namespace std; int N; int answer; vector<vector<int>> student; //(학생의 번호, {좋아하는 학생 번호 4개}) int board[21][21]; bool visited[21][21]; int dr[4] = { 0,0,1,-1 }; int dc[4] = { 1,-1,0,0 }; void init() { student = vector<vector<int>>(); for (int i = 0; i < 21; i++) { memset(board[i], 0, sizeof(board[i])); memset(visited[i], false, sizeof(visited[i])); } } void input() { cin >> N; for (int i = 0; i < N*N; i++) { vector<int> v; int num; for (int j = 0; j < 5; j++) { cin >> num; v.push_back(num); } student.push_back(v); } } bool inRange(int r, int c) { return r >= 0 && r < N && c >= 0 && c < N; } vector<pair<int, int>> getCondition2(vector<pair<int, int>> &v) { vector<pair<int, int>> result; int maxValue = 0; for (int i = 0; i < v.size(); i++) { int row = v[i].first; int col = v[i].second; int cnt = 0; for (int d = 0; d < 4; d++) { int nr = row + dr[d]; int nc = col + dc[d]; if (inRange(nr, nc) && board[nr][nc] == 0) { //비어있는지. cnt++; } } if (maxValue < cnt) { maxValue = cnt; result = { { row,col } }; } else if (maxValue == cnt) { result.push_back({ row,col }); } } return result; } bool comp(pair<int, int> p1, pair<int, int> p2) { if (p1.first == p2.first) return p1.second < p2.second; else return p1.first < p2.first; } int findPos(int num) { for (int i = 0; i < student.size(); i++) { if (student[i][0] == num) { return i; } } } int getPoint(int cnt) { if (cnt == 0) return 0; else if (cnt == 1) return 1; else { return pow(10, cnt - 1); } } int getSatisfaction() { int result = 0; for (int r = 0; r < N; r++) { for (int c = 0; c < N; c++) { int num = board[r][c]; int cnt = 0; for (int d = 0; d < 4; d++) { int nr = r + dr[d]; int nc = c + dc[d]; if (inRange(nr, nc)) { for (int s = 1; s < 5; s++) { int idx = findPos(num); if (board[nr][nc] == student[idx][s]) { cnt++; break; } } } } result += getPoint(cnt); } } return result; } void print() { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { cout << board[i][j] << " "; } cout << endl; } cout << endl; } void solve() { for (int i = 0; i < student.size(); i++) { // 조건1.비어있는 칸 중에서 좋아하는 학생이 인접한 칸에 가장 많은 칸 찾기. int condition1 = 0; vector<pair<int, int>> result_cond1; for (int r = 0; r < N; r++) { for (int c = 0; c < N; c++) { int cnt = 0; //인접 칸에 있는 좋아하는 사람 수 if (board[r][c] == 0) { //비어있는 칸 //인접한 칸에 좋아하는 학생있는지. for (int d = 0; d < 4; d++) { int nr = r + dr[d]; int nc = c + dc[d]; if (inRange(nr, nc)) { for (int s = 1; s < 5; s++) { if (board[nr][nc] == student[i][s]) { cnt++; } } if (condition1 < cnt) { condition1 = cnt; result_cond1 = { { r,c } }; } else if (condition1 == cnt) { result_cond1.push_back({ r,c }); } } } } } } result_cond1.erase(unique(result_cond1.begin(), result_cond1.end()), result_cond1.end()); //조건1 만족 if (result_cond1.size() == 1) { int row = result_cond1[0].first; int col = result_cond1[0].second; board[row][col] = student[i][0]; //print(); continue; } //조건2. 인접한 칸 중에서 비어있는 칸이 가장 많은 칸. vector<pair<int,int>> result_cond2 = getCondition2(result_cond1); //조건2 만족 if (result_cond2.size() == 1) { int row = result_cond2[0].first; int col = result_cond2[0].second; board[row][col] = student[i][0]; //print(); continue; } //조건3. 행 가장 작은칸 -> 열 작은칸 sort(result_cond2.begin(), result_cond2.end(), comp); board[result_cond2[0].first][result_cond2[0].second] = student[i][0]; //print(); } answer = getSatisfaction(); } 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.15 [백준] 마법사 상어와 토네이도 (0) 2021.10.15 [백준] 상어 중학교 (0) 2021.10.15 [백준] 마법사 상어와 비바라기 (0) 2021.10.14 [백준] 마법사 상어와 블리자드 (0) 2021.10.14