𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[λ°±μ€€] 16235번: λ‚˜λ¬΄ μž¬ν…Œν¬ - C++ λ³Έλ¬Έ

μ½”λ”©ν…ŒμŠ€νŠΈ μ€€λΉ„/λ°±μ€€

[λ°±μ€€] 16235번: λ‚˜λ¬΄ μž¬ν…Œν¬ - C++

.23 2025. 4. 4. 09:34
문제

πŸ”— 16235번: λ‚˜λ¬΄ μž¬ν…Œν¬

뢀동산 투자둜 μ–΅λŒ€μ˜ λˆμ„ 번 μƒλ„λŠ” 졜근 NΓ—N 크기의 땅을 κ΅¬λ§€ν–ˆλ‹€. μƒλ„λŠ” μ†μ‰¬μš΄ λ•… 관리λ₯Ό μœ„ν•΄ 땅을 1Γ—1 크기의 칸으둜 λ‚˜λˆ„μ–΄ λ†“μ•˜λ‹€. 각각의 칸은 (r, c)둜 λ‚˜νƒ€λ‚΄λ©°, r은 κ°€μž₯ μœ„μ—μ„œλΆ€ν„° 떨어진 칸의 개수, cλŠ” κ°€μž₯ μ™Όμͺ½μœΌλ‘œλΆ€ν„° 떨어진 칸의 κ°œμˆ˜μ΄λ‹€. rκ³Ό cλŠ” 1λΆ€ν„° μ‹œμž‘ν•œλ‹€.

 

μƒλ„λŠ” μ „μžν†΅μ‹ κ³΅ν•™κ³Ό μΆœμ‹ λ‹΅κ²Œ λ•…μ˜ 양뢄을 μ‘°μ‚¬ν•˜λŠ” λ‘œλ΄‡ S2D2λ₯Ό λ§Œλ“€μ—ˆλ‹€. S2D2λŠ” 1Γ—1 크기의 칸에 λ“€μ–΄μžˆλŠ” 양뢄을 쑰사해 μƒλ„μ—κ²Œ μ „μ†‘ν•˜κ³ , λͺ¨λ“  칸에 λŒ€ν•΄μ„œ 쑰사λ₯Ό ν•œλ‹€. κ°€μž₯ μ²˜μŒμ— 양뢄은 λͺ¨λ“  μΉΈμ— 5만큼 λ“€μ–΄μžˆλ‹€.

 

맀일 맀일 넓은 땅을 λ³΄λ©΄μ„œ λΏŒλ“―ν•œ ν•˜λ£¨λ₯Ό 보내고 있던 μ–΄λŠ λ‚  μ΄λŸ° 생각이 λ“€μ—ˆλ‹€.

λ‚˜λ¬΄ μž¬ν…Œν¬λ₯Ό ν•˜μž!

λ‚˜λ¬΄ μž¬ν…Œν¬λž€ μž‘μ€ 묘λͺ©μ„ ꡬ맀해 μ–΄λŠμ •λ„ ν‚€μš΄ ν›„ νŒ”μ•„μ„œ μˆ˜μ΅μ„ μ–»λŠ” μž¬ν…Œν¬μ΄λ‹€. μƒλ„λŠ” λ‚˜λ¬΄ μž¬ν…Œν¬λ‘œ 더 큰 λˆμ„ 벌기 μœ„ν•΄ M개의 λ‚˜λ¬΄λ₯Ό ꡬ맀해 땅에 μ‹¬μ—ˆλ‹€. 같은 1Γ—1 크기의 μΉΈμ— μ—¬λŸ¬ 개의 λ‚˜λ¬΄κ°€ 심어져 μžˆμ„ μˆ˜λ„ μžˆλ‹€.

 

이 λ‚˜λ¬΄λŠ” μ‚¬κ³„μ ˆμ„ 보내며, μ•„λž˜μ™€ 같은 과정을 λ°˜λ³΅ν•œλ‹€.

 

λ΄„μ—λŠ” λ‚˜λ¬΄κ°€ μžμ‹ μ˜ λ‚˜μ΄λ§ŒνΌ 양뢄을 λ¨Ήκ³ , λ‚˜μ΄κ°€ 1 μ¦κ°€ν•œλ‹€. 각각의 λ‚˜λ¬΄λŠ” λ‚˜λ¬΄κ°€ μžˆλŠ” 1Γ—1 크기의 칸에 μžˆλŠ” μ–‘λΆ„λ§Œ 먹을 수 μžˆλ‹€. ν•˜λ‚˜μ˜ 칸에 μ—¬λŸ¬ 개의 λ‚˜λ¬΄κ°€ μžˆλ‹€λ©΄, λ‚˜μ΄κ°€ μ–΄λ¦° λ‚˜λ¬΄λΆ€ν„° 양뢄을 λ¨ΉλŠ”λ‹€. λ§Œμ•½, 땅에 양뢄이 λΆ€μ‘±ν•΄ μžμ‹ μ˜ λ‚˜μ΄λ§ŒνΌ 양뢄을 먹을 수 μ—†λŠ” λ‚˜λ¬΄λŠ” 양뢄을 먹지 λͺ»ν•˜κ³  μ¦‰μ‹œ μ£½λŠ”λ‹€.

 

μ—¬λ¦„μ—λŠ” 봄에 죽은 λ‚˜λ¬΄κ°€ μ–‘λΆ„μœΌλ‘œ λ³€ν•˜κ²Œ λœλ‹€. 각각의 죽은 λ‚˜λ¬΄λ§ˆλ‹€ λ‚˜μ΄λ₯Ό 2둜 λ‚˜λˆˆ 값이 λ‚˜λ¬΄κ°€ 있던 칸에 μ–‘λΆ„μœΌλ‘œ μΆ”κ°€λœλ‹€. μ†Œμˆ˜μ  μ•„λž˜λŠ” 버린닀.

 

κ°€μ„μ—λŠ” λ‚˜λ¬΄κ°€ λ²ˆμ‹ν•œλ‹€. λ²ˆμ‹ν•˜λŠ” λ‚˜λ¬΄λŠ” λ‚˜μ΄κ°€ 5의 λ°°μˆ˜μ΄μ–΄μ•Ό ν•˜λ©°, μΈμ ‘ν•œ 8개의 칸에 λ‚˜μ΄κ°€ 1인 λ‚˜λ¬΄κ°€ 생긴닀. μ–΄λ–€ μΉΈ (r, c)와 μΈμ ‘ν•œ 칸은 (r-1, c-1), (r-1, c), (r-1, c+1), (r, c-1), (r, c+1), (r+1, c-1), (r+1, c), (r+1, c+1) 이닀. μƒλ„μ˜ 땅을 λ²—μ–΄λ‚˜λŠ” μΉΈμ—λŠ” λ‚˜λ¬΄κ°€ 생기지 μ•ŠλŠ”λ‹€.

 

κ²¨μšΈμ—λŠ” S2D2κ°€ 땅을 λŒμ•„λ‹€λ‹ˆλ©΄μ„œ 땅에 양뢄을 μΆ”κ°€ν•œλ‹€. 각 칸에 μΆ”κ°€λ˜λŠ” μ–‘λΆ„μ˜ 양은 A[r][c]이고, μž…λ ₯으둜 주어진닀.

K년이 μ§€λ‚œ ν›„ μƒλ„μ˜ 땅에 μ‚΄μ•„μžˆλŠ” λ‚˜λ¬΄μ˜ 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

μž…λ ₯

첫째 쀄에 N, M, Kκ°€ 주어진닀.

λ‘˜μ§Έ 쀄뢀터 N개의 쀄에 Aλ°°μ—΄μ˜ 값이 주어진닀. r번째 μ€„μ˜ c번째 값은 A[r][c]이닀.

λ‹€μŒ M개의 μ€„μ—λŠ” 상도가 심은 λ‚˜λ¬΄μ˜ 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ„Έ μ •μˆ˜ x, y, zκ°€ 주어진닀. 처음 두 개의 μ •μˆ˜λŠ” λ‚˜λ¬΄μ˜ μœ„μΉ˜ (x, y)λ₯Ό μ˜λ―Έν•˜κ³ , λ§ˆμ§€λ§‰ μ •μˆ˜λŠ” κ·Έ λ‚˜λ¬΄μ˜ λ‚˜μ΄λ₯Ό μ˜λ―Έν•œλ‹€.

 

좜λ ₯

첫째 쀄에 K년이 μ§€λ‚œ ν›„ 살아남은 λ‚˜λ¬΄μ˜ 수λ₯Ό 좜λ ₯ν•œλ‹€.

 

μ œν•œ

Β· 1 ≀ N ≀ 10

Β· 1 ≀ M ≀ N^2

Β· 1 ≀ K ≀ 1,000

Β· 1 ≀ A[r][c] ≀ 100

Β· 1 ≀ μž…λ ₯으둜 μ£Όμ–΄μ§€λŠ” λ‚˜λ¬΄μ˜ λ‚˜μ΄ ≀ 10

Β·  μž…λ ₯으둜 μ£Όμ–΄μ§€λŠ” λ‚˜λ¬΄μ˜ μœ„μΉ˜λŠ” λͺ¨λ‘ μ„œλ‘œ 닀름

 


 

S2D2

λ¬Έμ œκ°€ κΈΈμ§€λ§Œ 쑰건을 잘 따라가면 μ•Œκ³ λ¦¬μ¦˜μ΄λ‚˜ ν”„λ‘œμ„ΈμŠ€ μžμ²΄λŠ” 어렡지 μ•Šμ€ κ΅¬ν˜„ 문제.

κ·ΈλŸ¬λ‚˜ μ‹œκ°„ μ œν•œμ΄ 0.3초이기 λ•Œλ¬Έμ— νš¨μœ¨μ„±μ„ 생각해야 ν•œλ‹€.

 

 

Kλ…„μ˜ μ‹œκ°„μ„ λ³΄λ‚΄λ©΄μ„œ 4κ³„μ ˆλ§ˆλ‹€ ν•΄μ£ΌλŠ” 일이 μ •ν•΄μ Έμžˆλ‹€.

 

🌸 λ΄„ : μžμ‹ μ˜ λ‚˜μ΄λ§ŒνΌ 양뢄을 λ¨Ήκ³  λ‚˜μ΄ + 1, ν•˜λ‚˜μ˜ 칸에 μ—¬λŸ¬ 그루의 λ‚˜λ¬΄κ°€ μžˆλŠ” 경우, μ–΄λ¦° λ‚˜λ¬΄λΆ€ν„° 양뢄을 λ¨ΉλŠ”λ‹€. 양뢄을 먹으면 ν•œ 살을 더 λ¨Ήκ³ , μΆ©λΆ„ν•œ 양뢄을 μ„­μ·¨ν•˜μ§€ λͺ»ν•  경우 μ¦‰μ‚¬ν•œλ‹€.

🌊 여름 : 봄에 양뢄을 먹지 λͺ»ν•˜κ³  죽은 λ‚˜λ¬΄λ“€μ˜ μœ„μΉ˜μ—λŠ” 죽은 λ‚˜λ¬΄μ˜ λ‚˜μ΄/2 만큼 양뢄이 μΆ”κ°€λœλ‹€.

🍁 가을 : λ‚˜μ΄κ°€ 5의 λ°°μˆ˜κ°€ 된 λ‚˜λ¬΄λ§Œ, λ•…μ˜ λ²”μœ„μ— λ²—μ–΄λ‚˜μ§€ μ•ŠλŠ” ν•œ 8개의 λ°©ν–₯(β¬†οΈβ†—οΈβž‘οΈβ†˜οΈβ¬‡οΈβ†™οΈβ¬…οΈβ†–οΈ)으둜 μΈμ ‘ν•œ 땅에 λ‚˜μ΄κ°€ 1인 λ‚˜λ¬΄λ₯Ό μƒμ„±ν•œλ‹€.

❄️ 겨울 : S2D2κ°€ (i, j) 땅에 A[i][j] 만큼 양뢄을 μΆ”κ°€ν•œλ‹€(A 배열은 μž…λ ₯으둜 λ°›κ³ , 맀년 μ£ΌλŠ” 양은 κ³ μ •λ˜μ–΄μžˆμŒ)

 

겨울 -> 가을 -> 여름 -> λ΄„ 순으둜 κ΅¬ν˜„μ΄ 쉽기 λ•Œλ¬Έμ—, κ³„μ ˆμ˜ λ°˜λŒ€ 순으둜 κ΅¬ν˜„μ„ μ§„ν–‰ν–ˆλ‹€.

 

 

μ—¬κΈ°μ„œ μ•Œμ•„μ•Ό ν•˜λŠ” 것..

 

1. ν•˜λ‚˜μ˜ 칸에 μ—¬λŸ¬ 그루의 λ‚˜λ¬΄κ°€ μžˆμ„ 수 있기 λ•Œλ¬Έμ—, μ–΄λ¦° λ‚˜λ¬΄λΆ€ν„° 양뢄을 λ¨ΉλŠ”λ‹€λŠ” 쑰건이 μžˆλ‹€.

κ·Έλž˜μ„œ??μ—¬κΈ°μ„œ?? 1λ…„λ§ˆλ‹€ λ§€λ²ˆ sortλ₯Ό ν•˜κ³  있으면?? μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚œλ‹€.

 

βœ”οΈ 맀년 양뢄을 λ¨ΉλŠ” λͺ¨λ“  λ‚˜λ¬΄κ°€ 1μ‚΄μ”© κ³ μ •μ μœΌλ‘œ λ‚˜μ΄λ₯Ό 먹음

βœ”οΈ μƒˆλ‘œ μƒμ„±λ˜λŠ” λ‚˜λ¬΄λ“€μ€ λ‚˜μ΄κ°€ 1μ‚΄

➑️ λ”°λΌμ„œ μƒˆλ‘œ μƒμ„±λ˜λŠ” λ‚˜λ¬΄λ₯Ό νƒμƒ‰ν•˜λŠ” λ°°μ—΄μ˜ 'μ•žμͺ½μ—' λ°°μΉ˜ν•΄μ£Όλ©΄, 맀년 μ •λ ¬ν•  ν•„μš”κ°€ μ—†λ‹€.

 

λ”°λΌμ„œ μ΄ˆλ°˜μ— 단 ν•œλ²ˆλ§Œ μ •λ ¬ν•΄μ£Όκ³ ,

- μƒμ„±λ˜λŠ” λ‚˜λ¬΄λ“€ λ”°λ‘œ μ •μ˜

- κΈ°μ‘΄ λ‚˜λ¬΄λ“€μ„ λŒλ©΄μ„œ 죽은 λ‚˜λ¬΄ ꡬ별

- 살아남은 λ‚˜λ¬΄λ“€μ„ μƒˆ λ‚˜λ¬΄ 배열에 μ €μž₯

- μƒˆλ‘œμš΄ λ‚˜λ¬΄ 배열을 기쑴의 λ‚˜λ¬΄ 배열에 λ§μž…νžˆκΈ°

 

순으둜 μ§„ν–‰ν•˜λ©΄ 봄여름가을 λ™μž‘ 끝!

 

2. vector<vector<int>> vs vector<Struct>

κ°€μž₯ κ³ μƒν–ˆκ³  μ΄ν•΄μ•ˆλλ˜ λΆ€λΆ„..

κ²°λ‘ λΆ€ν„° λ§ν•˜μžλ©΄ 'κ³ μ •λœ' 길이의 자료 배열에 λŒ€ν•΄μ„œλŠ” vector<int> 보닀 ꡬ쑰체λ₯Ό μ •μ˜ν•˜λŠ” 것이 훨씬 νš¨μœ¨μ μ΄λΌλŠ” 것.

 

vector<vector<int> > tree(N, vector<int>(3));

vectorλŠ” μΈμ ‘κ·Έλž˜ν”„ ꡬ좕과 같이 '각 ν–‰μ˜ 크기가 가변적일 수 μžˆλŠ” 경우'에 μ ν•©ν•˜λ‹€.

각 ν–‰μ˜ vector듀이 λ³„λ„μ˜ vector둜 κ΄€λ¦¬λ˜κΈ° λ•Œλ¬Έμ—, 각 행에 λŒ€ν•΄ 좔가적인 λ©”λͺ¨λ¦¬ μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•  수 μžˆλ‹€. 즉, 각 행에 λŒ€ν•œ λ©”λͺ¨λ¦¬ 접근이 λΆ„μ‚°λ˜μ–΄ μžˆμ–΄ vector<struct>에 λΉ„ν•΄ λ©”λͺ¨λ¦¬ μ ‘κ·Ό 속도가 느릴 수 μžˆλ‹€.

 

struct Tree {
    int r, c, age;
    bool operator<(const Tree &t) const {
		return age < t.age;
	}
};

vector<Tree> tree(N);

κ΅¬μ‘°μ²΄λŠ” μŒ©λ°°μ—΄μ²˜λŸΌ λͺ¨λ“  데이터λ₯Ό 연속적인 λ©”λͺ¨λ¦¬ 블둝에 μ €μž₯ν•˜λ―€λ‘œ λ©”λͺ¨λ¦¬ μ˜€λ²„ν—€λ“œλ„ 적고 λ©”λͺ¨λ¦¬ 접근속도가 λΉ λ₯΄λ‹€.

κ΅¬ν˜„μ˜ λ³΅μž‘μ„±λ„ 있고, 각 ν–‰μ˜ 크기가 ꡬ쑰체 λ‚΄ λ³€μˆ˜λ§ŒνΌ κ³ μ •λ˜μ–΄ 있기 λ•Œλ¬Έμ— 가변적인 크기의 행을 μ²˜λ¦¬ν•˜κΈ° μ ν•©ν•˜μ§„ μ•Šμ§€λ§Œ,

 

이런 문제처럼 μ •μ˜ν•  λ³€μˆ˜κ°€ κ³ μ •λ˜μ–΄μžˆλŠ” 경우, ꡬ쑰체 배열을 μ •μ˜ν•˜λŠ” 것이 훨씬 더 효율적인 μ„±λŠ₯을 λ‚Ό 수 μžˆλ‹€.

 

10 1 1000
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
1 1 1

 

μ• λ¨Ήμ—‡λ˜ 1000λ…„ 예제..

struct vector vs 2차원 int 벑터

 

μ‹€ν–‰μ‹œκ°„ 차이λ₯Ό 봐도.. 거의 6λ°° 이상 μ°¨μ΄λ‚˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

 

μ½”λ“œ
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int N, M, K;
struct Tree {
    int r, c, age;
    bool operator<(const Tree &t) const {
		return age < t.age;
	}
};

vector<vector<int> > board;
vector<vector<int> > A;
vector<Tree> tree;

int dy[] = { 1, 0, -1, 0, 1, -1, 1, -1 }; // 8λ°©ν–₯ λ‚˜λ¬΄ 섀계
int dx[] = { 0, 1, 0, -1, 1, 1, -1, -1 };

void Four_seasons();

int main(void) {
    ios::sync_with_stdio(0);
	cin.tie(0);

    cin >> N >> M >> K;

    board.resize(N + 1, vector<int> (N + 1, 5)); // (r, c)λŠ” (1, 1)λΆ€ν„° μ‹œμž‘
    A.resize(N + 1, vector<int> (N + 1, 0));     // (r, c)λŠ” (1, 1)λΆ€ν„° μ‹œμž‘

    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 r, c, age;
        cin >> r >> c >> age;
        tree.push_back({r, c, age});
    }
    
    sort(tree.begin(), tree.end());
    Four_seasons();

    return 0;
}

void Four_seasons() {
    for(int year = 0; year < K; year++) {
        // Spring -> Autumn
        vector<Tree> new_tree;
        
        int tree_size = tree.size();

        for(int i = 0; i < tree_size; i++) {
            if(tree[i].age == 0) continue;

            int r = tree[i].r, c = tree[i].c;
            if(board[r][c] >= tree[i].age) {
                board[r][c] -= tree[i].age;
                tree[i].age++;

                if(tree[i].age % 5 == 0) {
                    for(int j = 0; j < 8; j++) {
                        if(r + dy[j] <= 0 || r + dy[j] > N || c + dx[j] <= 0 || c + dx[j] > N) continue;

                        new_tree.push_back({r + dy[j], c + dx[j], 1});
                    }
                }
            }
            else {
                tree[i].age *= -1;
            }
        }

        for(int i = 0; i < tree_size; i++) {
            if(tree[i].age < 0) {
                int r = tree[i].r, c = tree[i].c, age = tree[i].age * -1;
                board[r][c] += age / 2;
            }
            else {
                new_tree.push_back(tree[i]);
            }   
        }

        // Winter
       for(int i = 1; i <= N; i++)
            for(int j = 1; j <= N; j++)
                board[i][j] += A[i][j];

        tree.swap(new_tree);
    }

    cout << tree.size() << "\n";
}
Comments