1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/15312

 

15312번: 이름 궁합

영어 대문자 알파벳 26개의 획수는 순서대로 3, 2, 1, 2, 3, 3, 2, 3, 3, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1 로 정한다. (출제자가 알파벳 대문자를 쓰는 방법이 기준이다)

www.acmicpc.net

 

2) 설명

 그냥 영어 이름 궁합 보는 문제다.

여자친구랑 이름 궁합 봐보려고 풀어봤는데 궁합 정확도가 상당히 떨어지는 것 같다.

 

2. 풀이

1) 알고리즘

    : 단순 구현

 

2) 풀이 설명

재귀를 사용해서 풀어보았다.

그냥 원소 두 개 남을 때까지 이웃 원소들의 합 벡터( (1,2), (2,3), (3,4), ... , (N-1,N)를 반환하는 함수를 계속 재귀 호출했다.

 

3. 코드

더보기
/*
	이름 궁합
	단순 구현
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> solve(vector<int> nums){
	if(nums.size() == 2)
		return nums;
	vector<int> answer;
	for(int i=0;i<(int)nums.size()-1;i++)
		answer.push_back((nums[i]+nums[i+1])%10);

	return solve(answer);
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	vector<int> cnt = {3, 2, 1, 2, 3, 3, 2, 3, 3, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1};

	string jm, jh;
	cin >> jm >> jh;
	
	vector<int> nums;
	for(int i=0;i<jm.length();i++){
		nums.push_back(cnt[jm[i] - 'A']);
		nums.push_back(cnt[jh[i] - 'A']);
	}
	vector<int> result = solve(nums);
	for(auto r : result)
		cout << r;
	cout << endl;

	return 0;
}

 

4. 느낀점

- 재귀로 한번 풀어봤는데 비효율적이다.(시간적, 공간적 모두) 그렇지만 재미삼아 푼 문제라서 그냥 내비뒀다.

 -> 반복문으로 두 개씩 줄여가도록 풀면 빨라진다.

'알고리즘 > 백준' 카테고리의 다른 글

[백준/9252] LCS 2  (0) 2020.10.27
[백준/11501] 주식  (0) 2020.10.18
[백준/17070] 파이프 옮기기 1  (0) 2020.10.18
[백준/5557] 1학년  (1) 2020.10.18
[백준/1261] 알고스팟  (0) 2020.10.16

1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/17070

 

17070번: 파이프 옮기기 1

유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의

www.acmicpc.net

 

2) 설명

길이 2의 파이프가 있다.

파이프는 가로, 세로, 대각선(좌상단 -> 우하단) 방향으로 밀 수 있다.

처음에 (1, 1), (1, 2)에 놓여진 파이프를 (N, M)까지 미는 경우의 수를 구하면 된다.

단 파이프는 오른쪽, 아래쪽, 대각선으로만 밀 수 있고, 직각으로는(가로 -> 세로, 세로->가로) 밀 수 없다.

또한 파이프의 이동 경로는 반드시 빈 칸이어야 하고, 대각선의 경우에는 파이프가 놓여져 있는 총 4칸이 빈 칸이어야 한다.

2. 풀이

1) 알고리즘

    : DP

 

2) 풀이 설명

3차원 DP 벡터를 사용했다.

예를 들어 dp[x][y][z]는 x 방식(0 : 가로, 1 : 세로, 2 : 대각선)으로 (y, z)에 도달하는 경우의 수를 나타낸다.

2차원 DP를 사용하지 않고 이동 방식까지 나누어 3차 DP를 사용한 이유는 이동 방식(가로, 세로, 대각선)에 따라 다음에 이동할 수 있는 방식이 달라지기 때문이다.

 

모든 dp를 0으로 초기화해주고 가로 방식의 첫 행만 1로 초기화해주었다.

 

(i, j)로 이동하는 경우의 수는 다음과 같다.

1. (i, j-1)에서 가로 이동 (단 (i, j-1)에서는 세로로 도달했으면 안 된다.)

2. (i-1, j)에서 세로 이동 (단 (i-1, j)에서는 가로로 도달했으면 안 된다.)

3. (i-1, j-1)에서 대각선 이동

 

그러므로 점화식은 다음과 같이 세워진다.

dp[0][i][j] = dp[0][i][j-1] + dp[2][i][j-1]

dp[1][i][j] = dp[1][i-1][j] + dp[2][i-1][j]

dp[2][i][j] = dp[0][i-1][j-1] + dp[1][i-1][j-1] (단 좌하단, 우상단이 빈 공간일 때)

 

이렇게 다 돌고나면

dp[0][N][M] // 마지막에 가로 방식으로 (N, M)에 도달하는 경우의 수

+ dp[0][N][M] // 마지막에 세로 방식으로 (N, M)에 도달하는 경우의 수

+ dp[0][N][M] // 마지막에 대각선 방식으로 (N, M)에 도달하는 경우의 수

 

이 답이 된다.

 

3. 코드

더보기

 

/*
	파이프 옮기기 1
	알고리즘
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	int N, answer = 0;
	cin >> N;

	vector<vector<int>> house(N+1, vector<int>(N+1));
	/*
		0 - 가로
		1 - 세로
		2 - 대각선
	*/
	vector<vector<vector<int>>> dp(3,vector<vector<int>>(N+1, vector<int>(N+1, 0)));

	for(int i=1;i<=N;i++)
		for(int j=1;j<=N;j++)
			cin >> house[i][j];

	for(int i=2;i<=N && !house[1][i];i++)
		dp[0][1][i] = 1;

	for(int i=2;i<=N;i++){
		for(int j=2;j<=N;j++){
			if(!house[i][j]){
				dp[0][i][j] = dp[0][i][j-1] + dp[2][i][j-1];
				dp[1][i][j] = dp[1][i-1][j] + dp[2][i-1][j];
				if(!house[i-1][j] && !house[i][j-1]){
					dp[2][i][j] = dp[0][i-1][j-1] + dp[1][i-1][j-1] + dp[2][i-1][j-1];
				}
			}
		}
	}
	for(int i=0;i<3;i++)
		answer += dp[i][N][N];
	
	cout << answer << endl;

	return 0;
}

 

4. 느낀점

 - 초기에 (1, 1), (1, 2)에 파이프가 놓여져있다는 걸 모르고 가로, 세로, 대각선 다 출발했다가 틀렸다. 역시 문제를 잘 읽어야 한다.

'알고리즘 > 백준' 카테고리의 다른 글

[백준/11501] 주식  (0) 2020.10.18
[백준/15312] 이름 궁합  (1) 2020.10.18
[백준/5557] 1학년  (1) 2020.10.18
[백준/1261] 알고스팟  (0) 2020.10.16
[백준/9655] 돌 게임  (0) 2020.10.16

1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/5557

 

5557번: 1학년

상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀��

www.acmicpc.net

 

2) 설명

숫자 배열이 있으면 마지막 숫자 전에 = 기호를, 나머지 각 숫자 사이에 +나 - 기호를 넣어서 등식을 성립하게 만들 수 있는 경우의 수를 구하면 된다.

단 계산 과정 중(왼쪽부터 계산하는 방식) 음수나 20을 초과하는 수가 나와서는 안 된다.

2. 풀이

1) 알고리즘

    : DP

 

2) 풀이 설명

 

0 ~ N-2 까지의 입력받은 숫자를 더하고 빼서 N-1번째에 입력받은 숫자를 만들어내면 된다.

즉 nums[0], nums[1], ... ,nums[N-2] 를 더하고 빼서 nums[N-1]을 만들면 된다.

 

그래서 i번째 이전 숫자들을 더하고 빼서 0부터 20까지 각각의 숫자를 만들 수 있는 경우의 수를 저장하는 DP 배열을 만들었다.

ex) DP[10][4] 에는 nums[0], nums[1], nums[2], nums[3], nums[4] 를 더하고 빼서 10을 만들 수 있는 경우의 수가 들어있다.

그러므로 DP배열은 21행( 0 ~ 20 ), N-1열( 0 ~ N-2 )을 가지게 된다.

초기값은 첫번째 DP[nums[0]][0] = 1로 주어진다.(첫 수(nums[0])으로 nums[0]을 만드는 경우의 수는 하나이기 때문에)

또한 점화식은 아래와 같이 세워진다.

 

DP[x][i] = DP[x][i] + DP[x-nums[i]] (단 x-nums[i] >= 0)

DP[x][i] = DP[x][i] + DP[x+nums[i]] (단 x+nums[i] <= 20)

 

이렇게 N-2열까지 돌리고나면 DP[nums[N-1]][N-2] 값이 답이 된다.(nums[0], nums[1], ... , nums[N-2]를 사용해서 nums[N-1]을 만드는 경우의 수)

 

3. 코드

더보기
/*
	1학년
	DP
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	const int maxSum = 20;
	int N;
	cin >> N;

	vector<int> nums(N);

	for(int i=0;i<N;i++)
		cin >> nums[i];

	vector<vector<long long>> DP(21, vector<long long>(N, 0));
	
	DP[nums[0]][0] = 1;

	for(int i=1;i<N-1;i++){
		for(int j=0;j<=maxSum;j++){
			if(j-nums[i] >= 0)
				DP[j][i] += DP[j-nums[i]][i-1];
			if(j+nums[i] <= maxSum)
				DP[j][i] += DP[j+nums[i]][i-1];
		}
	}

	cout << DP[nums[N-1]][N-2] << "\n";

	return 0;
}

 

4. 느낀점

 

 - 값의 범위 잘 생각하기(long long 줘야하는데 int로 선언해서 틀렸었다.)

 - 가독성 높은 점화식 세우기

'알고리즘 > 백준' 카테고리의 다른 글

[백준/15312] 이름 궁합  (1) 2020.10.18
[백준/17070] 파이프 옮기기 1  (0) 2020.10.18
[백준/1261] 알고스팟  (0) 2020.10.16
[백준/9655] 돌 게임  (0) 2020.10.16
[백준/7569] 토마토  (0) 2020.10.10

1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/1261

 

1261번: 알고스팟

첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미

www.acmicpc.net

 

2) 설명

0(빈 공간), 1(벽)로 이루어진 미로가 있고 (1, 1)에서 (N, M)으로 도달하면서 1(벽)을 최소한으로 뚫고 갈 때, 뚫고 간 벽의 수를 구하는 문제.

2. 풀이

1) 알고리즘

    : 우선순위 큐, BFS

 

2) 풀이 설명

  처음에는 DFS를 사용하면 되겠다 생각했지만 BFS와 우선순위 큐를 사용하는 게 편하다고 생각했다.

일반적인 BFS문제를 풀듯이 풀었으나 큐 대신 우선순위 큐에 튜플( - 뚫은 벽의 수, x 좌표, y 좌표)를 넣어줬다.

우선순위 큐는 맥스 힙 방식(가장 큰 값부터 빼는 방식)으로 동작하기 때문에 뚫은 벽의 수를 음수처리 해줌으로써 가장 적게 벽을 뚫은 노드부터 빼오도록 했다.

 

ex) ㄱ : (-3, 2, 4)와 ㄴ : (-10, 3, 5)가 있으면 ㄱ은 벽을 3번, ㄴ은 벽을 10번 뚫은 것이고, 우선순위 큐에서는 -3 > -10 이기 때문에 ㄱ을 먼저 뽑는다.

 

즉 해당 노드를 처음 방문한다면 그 방문은 벽을 최소로 뚫는 경로로 방문한 것이 된다.

그러므로 BFS를 돌던 중 (N, M) 좌표를 방문한다면 바로 while문을 탈출하고 답을 내면 된다.

 

3. 코드

더보기
/*
	알고스팟
    BFS, Priority queue
*/
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <tuple>

using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	int dx[4] = {-1, 1, 0, 0};
	int dy[4] = {0, 0, -1, 1};

	int N, M, answer = -1;
	cin >> M >> N;
	
	vector<vector<char>> miro(N+1, vector<char>(M+1));
	vector<vector<bool>> visited(N+1, vector<bool>(M+1, false));

	priority_queue<tuple<int, int, int>> pq;

	for(int i=1;i<=N;i++)
		for(int j=1;j<=M;j++)
			cin >> miro[i][j];

	pq.push({0, 1, 1});
	visited[1][1] = true;

	while(!pq.empty()){
		int wall = get<0>(pq.top());
		int x = get<1>(pq.top());
		int y = get<2>(pq.top());
		pq.pop();
		
		if(x==N && y==M){
			answer = -wall;
			break;
		}
		for(int i=0;i<4;i++){
			int nx = x + dx[i];
			int ny = y + dy[i];

			if(nx<=0 || nx>N || ny<=0 || ny>M)
				continue;
			if(visited[nx][ny])
				continue;
			
			visited[nx][ny] = true;
			pq.push({(miro[nx][ny]=='1'? wall-1 : wall), nx, ny});
		}
	}
	
	cout << answer << endl;

	return 0;
}

 

 

4. 느낀점

 - 입력이 M, N 순서로 주어져서 일반적으로 생각하는 방식(N -> M)이랑 달라서 헷갈렸다.

 - visited를 안 써도 되지 않을까 잠시 생각했다. -> 무한루프 돌 수도 있다.

 - 인풋 한 줄을 한 글자씩 받아야 하는 걸 그냥 int로 받아버렸다. 입력 받기 신경쓰자.

 - 아직 tuple 사용법이 많이 미숙하다. 연습하자.

'알고리즘 > 백준' 카테고리의 다른 글

[백준/17070] 파이프 옮기기 1  (0) 2020.10.18
[백준/5557] 1학년  (1) 2020.10.18
[백준/9655] 돌 게임  (0) 2020.10.16
[백준/7569] 토마토  (0) 2020.10.10
[백준/2606] 바이러스  (0) 2020.10.10

1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/9655

 

9655번: 돌 게임

상근이가 게임을 이기면 SK를, 창영이가 게임을 이기면 CY을 출력한다.

www.acmicpc.net

2) 설명

상근이와 창영이가 N개의 돌을 차례로 1개 혹은 3개씩 가져가면서 마지막 돌을 가져가는 사람이 이기는 게임을 한다.

상근이가 선공이고 둘 다 최선을 다할 때 누가 이기는지 출력하는 문제.(상근 SK, 창영 CY)

2. 풀이

1) 알고리즘

    : DP

 

2) 풀이 설명

  간단한 DP 문제.

N번째 돌을 반드시 집기 위해선 N-2번째 돌을 가져가면 된다.

내가 N-2번째 돌을 집으면 돌은 두 개가 남고 상대방은 1개, 3개의 돌만 가져갈 수 있기 때문에, 즉 남은 두 개 중 1개만 가져갈 수밖에 없기 때문에 상대가 돌 1개를 가져가고 마지막 N번째 돌을 가져오면 된다.

그러므로 초기값 A1 = 상근이가 이기는 경우, A2 = 창영이가 이기는 경우로 두고 N번까지 A_N = A_(N-2)을 돌리면 된다.

나는 bool 타입으로 dp값을 저장했다. 상근이가 이기는 경우 = true, 창영이가 이기는 경우 = false

 

3. 코드

더보기
/*
	돌 게임
	DP
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

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

	int N;
	cin >> N;
	
	vector<bool> dp(N+1);

	dp[1] = true;
	dp[2] = false;

	for(int i=3;i<=N;i++)
		dp[i] = dp[i-2];
		 
	cout << (dp[N]? "SK\n" : "CY\n");

	return 0;
}

 

 

4. 느낀점

 - 1차원 dp(점화식) 감잡기 좋은 문제라고 생각한다.

'알고리즘 > 백준' 카테고리의 다른 글

[백준/17070] 파이프 옮기기 1  (0) 2020.10.18
[백준/5557] 1학년  (1) 2020.10.18
[백준/1261] 알고스팟  (0) 2020.10.16
[백준/7569] 토마토  (0) 2020.10.10
[백준/2606] 바이러스  (0) 2020.10.10

1. 문제

1) 문제 링크

    : www.acmicpc.net/problem/7569

 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net

 

2) 설명

토마토가 다 익는 데 걸리는 시간(처음부터 모두 익어있었다면 0, 다 익을 수 없는 상황이면 -1)을 구하는 문제.

안 익은 토마토 = 0

토마토가 없는 칸 = -1

익은 토마토 = 1

로 주어지고 익은 토마토 주변의 안 익은 토마토들이 익는다.

 

 

2. 풀이

1) 알고리즘

   : BFS

 

2) 풀이 설명

예전에 풀었던 문제지만 다시 한번 풀어봤다.

 

전형적인 BFS문제다.

 

토마토 익을 때까지 큐에 넣다 뺐다 하면서 계속 돌리면 된다.

 

bfs에서 자주 사용하는 visited 배열(방문 확인을 위한)을 사용하지 않은 이유는 0인 칸을 방문하게 되면 (이전 칸 + 1) 값으로 계속 업데이트 해주기 때문에 각 칸이 0일 때만 다음에 방문할 수 있는 칸이 되기 때문이다. 

 

다 돌리고 box에 0(안 익은 토마토)가 남았다면 -1 리턴해주면 된다.

 

처음부터 다 익은 상황이었으면 answer 값이 1이 되므로 마지막에 출력하는 (answer - 1)이 0이 되어서, 모두 잘 익은 상황, 처음부터 모두 익은 상황을 커버할 수 있다.

 

3. 코드

더보기

 

/*
	토마토(3차원)
	BFS
	난이도 
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <tuple>

using namespace std;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	int answer = 0;
	int M, N, H;
	cin >> M >> N >> H;

	vector<vector<vector<int>>> box(H, vector<vector<int>>(N, vector<int>(M, 0)));
	queue<tuple<int, int, int>> q;
	int dx[6] = {-1, 1, 0, 0, 0, 0};
	int dy[6] = {0, 0, -1, 1, 0, 0};
	int dz[6] = {0, 0, 0, 0, -1, 1};
	
	//입력
	for(int i=0;i<H;i++){
		for(int j=0;j<N;j++){
			for(int k=0;k<M;k++){
				cin >> box[i][j][k];
				if(box[i][j][k] == 1)
					q.push({i, j, k});
			}
		}
	}
	//BFS 시작
	while(!q.empty()){
		int z = get<0>(q.front());
		int x = get<1>(q.front());
		int y = get<2>(q.front());
		q.pop();

		for(int i=0;i<6;i++){
			int nx = x + dx[i];
			int ny = y + dy[i];
			int nz = z + dz[i];

			if(nx<0 || nx>=N || ny<0 || ny>=M || nz<0 || nz>=H)
				continue;
			if(box[nz][nx][ny] != 0)
				continue;
			box[nz][nx][ny] = box[z][x][y] + 1;
			q.push({nz, nx, ny});
		}
	}

	//다 익을 수 없는 경우 체크, 토마토가 익는 데 걸리는 최대 시간 찾기
	for(int i=0;i<H;i++){
		for(int j=0;j<N;j++){
			for(int k=0;k<M;k++){	
				if(box[i][j][k] == 0){
					cout << "-1\n";
					return 0;
				}
				answer = max(answer, box[i][j][k]);
			}
		}
	}
	
	//1부터 셌으니까 -1 해서 출력
	cout << answer - 1 << "\n";

	return 0;
}

 

4. 느낀점

1) 잘 안 다뤄본 3차원 BFS를 하다 보니까 인덱스 설정이 헷갈려서 실수를 많이 했다.

2) 마지막에 안 익은 토마토가 있는지 확인하기 위한 루프를 돌아서 그런지 다른 풀이들보다 시간이 약간 더 걸린다.

   -> 변수가 많아지더라도 시간을 절약하는 것이 좋은지, 가시성과 명확성을 높이기 위해 각 프로세스를 구분하는 게 좋은지 고민해보야 할 것 같다.

3) 3차원 벡터 초기화와 함께 선언하는 게 많이 귀찮다. 더 편한 방법이 있는지 찾아보면 좋을 것 같다.

'알고리즘 > 백준' 카테고리의 다른 글

[백준/17070] 파이프 옮기기 1  (0) 2020.10.18
[백준/5557] 1학년  (1) 2020.10.18
[백준/1261] 알고스팟  (0) 2020.10.16
[백준/9655] 돌 게임  (0) 2020.10.16
[백준/2606] 바이러스  (0) 2020.10.10

1. 문제

문제 링크 : www.acmicpc.net/problem/2606

 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어��

www.acmicpc.net

컴퓨터 간의 연결 정보가 주어지고 바이러스에 감염된 컴퓨터와 연결된 컴퓨터들이 감염된다.

1번 컴퓨터에 의해서 감염되는 컴퓨터의 개수를 구하는 문제.

 

2. 풀이

전형적인 DFS, BFS 문제(저는 DFS로 풀어봤습니다).

dfs 함수는 자기 자신을 포함해서 자기 자신으로부터 감염되는 컴퓨터들의 개수를 리턴합니다.

연결된 컴퓨터를 방문할 때 방문한 적이 있다면 그 컴퓨터는 이미 감염된 컴퓨터이므로 0을 리턴해줍니다.

ex) (2, 3), (2, 4), (2, 7) 연결쌍이 있고 어느 컴퓨터도 방문한 적이 없다면 다면 2, 3, 4, 7 총 4를 리턴

다만 1번 컴퓨터에 의해서 감염되는 컴퓨터의 개수를 구하는 것이므로 최종 결과값에서 1번 컴퓨터를 빼줘야 합니다.

 

 

3. 코드

더보기

 

/*
	바이러스
	DFS
	난이도
*/
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int N, M;
vector<vector<int>> links; // 컴퓨터 간 연결 정보
vector<bool> visited; // 방문 확인

int dfs(int cur){
	if(visited[cur])
		return 0;
	visited[cur] = true;
	int cnt = 1; // 자신이 감염되므로 1부터 시작한다.
	for(auto next : links[cur])
		cnt += dfs(next);
	return cnt;
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	cin >> N >> M;

	links.reserve(N+1);
	visited.reserve(N+1);

	fill(visited.begin(), visited.end(), false);
	
	for(int i=0;i<M;i++){
		int a, b;
		cin >> a >> b;
		links[a].push_back(b);
		links[b].push_back(a);
	}

	cout << dfs(1) - 1 << endl; // 1번 노드 제외

	return 0;
}

 

4. 느낀점

1) 블로그 개설하고 처음 올리는 거라 포맷 등 포스팅에 부족함을 많이 느꼈다.

2) 코드의 길이와 가시성 사이에 고민하다보니 코드가 이도저도 아니게 되는 것 같다.(전역변수 사용 + reserve 사용, answer 미사용 등)

'알고리즘 > 백준' 카테고리의 다른 글

[백준/17070] 파이프 옮기기 1  (0) 2020.10.18
[백준/5557] 1학년  (1) 2020.10.18
[백준/1261] 알고스팟  (0) 2020.10.16
[백준/9655] 돌 게임  (0) 2020.10.16
[백준/7569] 토마토  (0) 2020.10.10

+ Recent posts