| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- 도커 #docker #docker-compose.yml #도커컴포즈 #배포 #spring #mysql #docker-compose
- 도커 #Docker #배포 #Spring #MySQL #백엔드배포
- /
- chatgpt #gpt #챗지피티 #ai
- Today
- Total
개발자 데뷔!
[21610] 마법사 상어와 비바라기 본문
구현, 시뮬레이션
삽질한 부분
1. init 함수 따로 없이 memset을 필요한 부분에 배치해 초기화
- move_cloud() 함수 : newCloud 배열 초기화
- create_cloud() 함수 : Cloud 배열 초기화
2. 이동방향은 미리 vector에 입력받아 저장하고, move_cloud()함수에 몇번째 입력을 사용할 것인지
함수파라미터로 받아야함
3. 범위밖의 방향 보정
-> 행,열의 시작-끝을 이음 (범위밖으로 벗어날시 index 0으로 다시 옮김)
*(nr + N)%N으로 할시 오류발생 !! *** -로 할 시 나머지값 (index)가 오염됨
100은 명령횟수 M의 최댓값 기준
nr = (nr + N*100) % N;
nc = (nc + N*100) % N;
4. 첫 구름위치 미리 setting해야됨!
TIL
1. [ERROR] cout이 모호합니다.
=> cout이 main 함수의 바깥에 위치할 때 발생.
주로 주석 처리/해제 시, 인식오류로 발생함.
해결: ctrl+s로 코드를 재저장하거나, 지웠다 다시 써 인식시키기
2. [WARNINGS] 버퍼오버런이 발생했습니다. 쓰기 가능한 크기는 ~ 인데 실제로는 ~만 쓸 수 있습니다.
=> 버퍼의 읽기 가능한 범위는 버퍼에서 읽는 데 사용되는 인덱스보다 작을 수 있습니다. 유효한 범위를 벗어난 데이터를 읽으려고 시도하면 버퍼 오버런이 발생합니다.
3. memset ***
배열 등 초기화 하는 함수.
1차원 벡터, 2차원 벡터 모두 사용법 동일
for문보다 빠름
a. 다음과 같은 라이브러리 포함
#include <cstring>
* [c++] : cstring / [c] : string.h
* visualstudio 와 SWEA의 컴파일 환경이 조금 달라 라이브러리 포함 여부가 다름 !
b. 사용방법
memset(배열 시작 주소, 초기화할 값, 초기화할 size)
memset(arr, 0, sizeof(arr));
4. 범위밖의 방향 보정(잇기) ***
-> 행,열의 시작-끝을 이음 (범위밖으로 벗어날시 index 0으로 다시 옮김)
a. 내방식
처음 (nr+N) % N 으로 하니, => 오류발생!! **
이동을 1<= M <= 100 만큼 할 수 있으므로, M이 매우 크다면
원래 위치 에서 M번 (-) 방향으로 이동한 위치 nr이 -43 같이 매우 큰 음수일 수 있고,
이 nr에 지도범위 N을 더하더라도, 값이 0보다 커지지 않아 index가 될 나머지값이 오염될 수 있다.
=> 즉, 명령횟수 M의 최댓값 기준 100 을 곱해 더해주는 방식으로 해결함
nr = (nr + N*100) % N;
nc = (nc + N*100) % N;
b. 다른 사람 방식
이동횟수인 s를 직접 곱해서 사용 !!
nr = (nr + N * s) % N;
nc = (nc + N * s) % N;
5. queue에 pair 값 넣기! ***
나는 코드에서, vector<int> plan[2]; 를 넣는 방식을 선택했지만,
두 값의 index가 명확히 일치하지 않을 수 있으므로 불안정하다. 이 때 pair를 사용하는게 좋다.
a. 라이브러리 포함 [<queue> 포함 / <pair>는 미포함]
<pair>는 #include<utility>의 헤더파일에 존재하는 STL이다.
그러나, <algorithm>, <vector>등 헤더파일에 이미 포함되어 있으므로 따로 <utility>를 포함하지 않아도 된다.
#include <queue>
b. 선언
queue<pair<int,int>> q;
c. 값 입력 ***
q.push(make_pair(0,1));
d. 값 추출 ***
int x = q.front().first;
int y = q.front().second;
e. front와 pop의 차이
- [pop] : front값을 삭제 (반환 X) q.pop()
- [front] : front값을 반환 (삭제 X) q.front()
다음과 같은 사용은 pop()함수에 반환 값이 없으므로 출력할 수 없고, 사용불가하다.
즉, 출력과 함께 확인하며 사용하고 싶은 경우 front, pop 을 번갈아 함깨 사용해야 한다.
cout << q.pop(); // 오류 뜸
f. 크기
int size = q.size();
정답코드
#include<vector>
#include<algorithm>
#include<iostream>
#include<cstring>
//#include<fstream>
#define MAX 51
using namespace std;
//for test
//ifstream fin("input.txt");
//ofstream fout("output.txt");
int N, M;
int Map[MAX][MAX];
int Cloud[MAX][MAX];
int newCloud[MAX][MAX] = {0};
vector<int> Plan[2]; // 구름이 움직일 계획 ds 저장
int direct[8][2] = { {0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1} };
int diag_direct[4][2] = { {-1,-1},{-1,1},{1,1},{1,-1} };
void move_cloud(int n) { // n : 몇번째 움직임 인지 알기 위함
memset(newCloud, 0, sizeof(newCloud)); // newCloud 초기화 ***
int dir = Plan[0][n]; // 방향
int recur = Plan[1][n]; // 횟수
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (Cloud[i][j] == 1) {
int nr = i + recur * direct[dir][0];
int nc = j + recur * direct[dir][1];
nr = (nr + N*100) % N; // 나머지 계산에 오류 나올 수 있으므로 *100 최대 횟수로 해준 후 나누기 !! ***
nc = (nc + N*100) % N;
newCloud[nr][nc] = 1;
// 비내림
Map[nr][nc] += 1;
}
}
}
}
int check(int r, int c) {
int cnt = 0;
for (int i = 0; i < 4; i++) {
int nr = r + diag_direct[i][0];
int nc = c + diag_direct[i][1];
if (nr < 0 || nc < 0 || nr >= N || nc >= N)
continue;
if (Map[nr][nc] > 0)
cnt++;
}
return cnt;
}
void copy_water() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (newCloud[i][j] == 1) {
Map[i][j] += check(i,j);
}
}
}
}
void create_cloud() {
memset(Cloud, 0, sizeof(Cloud)); // 배열 초기화 하는법 !! **** memset 이 for문 보다 빠름 ! ***
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// 구름이 없었고, 물이 2 이상인 곳
if (newCloud[i][j] == 0 && Map[i][j] >= 2) {
Cloud[i][j] = 1;
Map[i][j] -= 2;
}
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
// 0. input 받기
int answer = 0;
int d, s;
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> Map[i][j];
}
}
for (int i = 0; i < M; i++) {
cin >> d >> s;
d--; // 방향만 값 보정!! ***
Plan[0].push_back(d);
Plan[1].push_back(s);
}
// 1. setting // index 하나씩 더 빼는거 주의!!
Cloud[N - 1][0] = 1; // 버퍼 오버런 발생 ??????????
Cloud[N - 1][1] = 1;
Cloud[N - 2][0] = 1;
Cloud[N - 2][1] = 1;
// 2. 실행
for (int i = 0; i < M; i++) {
//play
move_cloud(i); // newCloud 초기화 시점 // 0 이 아닌 i넣어줘야 옳게 풀림! ***
copy_water();
create_cloud(); // Cloud 초기화 시점
}
// 3. 정답 계산
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
answer += Map[i][j];
}
}
cout << answer;
//for test
//fin.close();
//fout.close();
return 0;
}
'코딩테스트 > 삼성기출' 카테고리의 다른 글
| [5373] 큐빙 (0) | 2022.04.30 |
|---|---|
| [23288] 주사위 굴리기2 (0) | 2022.04.29 |
| [23290] 마법사 상어와 복제 (0) | 2022.04.27 |