728x90
반응형
https://www.acmicpc.net/problem/21610
21610번: 마법사 상어와 비바라기
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기
www.acmicpc.net
문제풀때 주의해야할점
1. 새로운 구름 위치를 표시할때 예를들어
(4,1)->(1,1)
(1,1)>(2,1)
이처럼 이동할때 (4,1)을 배열에서 값을 0으로 만들고 (1,1)을 1로 바꾸는것처럼 알고리즘을 짜면 뒤에서 (1,1)->(2,1)에서 새로 갱신해서 1로 있어야할 값을 0으로 바꿔버린다. 그래서 그냥 새로운 배열을 만들고, 다시 기존 배열에 복사하는게 낫다.
다른 답안안보고 풀어서 뿌듯하다..
#include<iostream>
#include<vector>
#include<cmath>
#include<deque>
using namespace std;
int A[55][55]; //바구니에 저장된 물의 양
vector<pair<int, int>>info;
int dr[9] = {0,0,-1,-1,-1,0,1,1,1};
int dc[9] = {0,-1,-1,0,1,1,1,0,-1};
int N, M;
vector<pair<int, int>>cloud;
vector<pair<int, int>>cloud3;
vector<vector<int>>rainy_cloud;
void make_cloud() { //구름 정보
for (int i = N - 1; i <= N; i++) {
for (int j = 1; j <= 2; j++) {
rainy_cloud[i][j] = 1;
cloud.push_back({ i,j }); //현재 구름 정보
}
}
}
//1.구름 이동
void move_cloud(int d, int s) {
int move = s % N; //움직이는 칸 갯수
vector<vector<int>>rainy_cloud2;
rainy_cloud2.assign(55, vector<int>(55, 0));
for (int i = 0; i < cloud.size(); i++) {
int r = cloud[i].first;
int c = cloud[i].second;
int nr = r + dr[d] * move;
int nc = c + dc[d] * move;
if (nr > N)nr -= N;
if (nc > N)nc -= N;
if (nr < 1)nr += N;
if (nc < 1)nc += N;
cloud3.push_back({ nr,nc });
rainy_cloud2[nr][nc] = 1;
}
rainy_cloud = rainy_cloud2;
}
//2. 물증가 +1
void rains() {
//durlqnxj answpdlTdma
for (int i = 0; i < cloud3.size(); i++) {
A[cloud3[i].first][cloud3[i].second]= A[cloud3[i].first][cloud3[i].second]+1;
}
}
//4. 물복사버스 마법
void new_magic() {
for (int i = 0; i < cloud3.size(); i++) {
int r = cloud3[i].first;
int c = cloud3[i].second;
int sum = 0;
for (int i = 2; i <= 8; i+=2) {
int nr = r + dr[i];
int nc = c + dc[i];
if (nr<1 || nr>N || nc<1 || nc>N)continue;
if (A[nr][nc])sum++;
}
A[r][c] += sum;
}
}
//새로운 구름 생기기
void new_cloud() {
vector<pair<int, int>>cloud2;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (A[i][j] >= 2 && !rainy_cloud[i][j]) {
cloud2.push_back({ i,j });
A[i][j] -= 2;
}
}
}
; cloud = cloud2;
//갱신하기
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
rainy_cloud[i][j] = 0;
}
}
for (int i = 0; i < cloud.size(); i++) {
rainy_cloud[cloud[i].first][cloud[i].second] = 1;
}
vector<pair<int, int>>t;
cloud3 = t;
}
int cnt() {
int ans = 0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
ans += A[i][j];
}
}
return ans;
}
int main() {
rainy_cloud.assign(55, vector<int>(55, 0));
for (int i = 0; i < 55; i++) {
for (int j = 0; j < 55; j++) {
A[i][j] = 0;
}
}
cin >> N >> M;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
cin >> A[i][j];
}
}
//구름 이동정보
for (int i = 0; i < M; i++) {
int d, s;
cin >> d >> s;
info.push_back({ d,s });
}
//비구름 만들기
make_cloud();
//m번 구름 이동시키기
for (int i = 0; i < M; i++) {
//1.구름 d방향으로 s칸 이동시키기
move_cloud(info[i].first, info[i].second);
//2. 구름이 있는 칸에 물+1 wnd
rains();
//3.물복사버그 마법
new_magic();
new_cloud();
}
//물의 양 계산
cout<<cnt();
return 0;
}
728x90
반응형
'알고리즘 > 삼성 sw 역량테스트 기출문제' 카테고리의 다른 글
백준 20057 마법상어와 토네이도(c++) (0) | 2023.04.07 |
---|---|
백준 14501번 퇴사(C++) (0) | 2023.03.19 |