728x90
 

1010번: 다리 놓기

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

www.acmicpc.net

서쪽에 있는 사이트의 개수 n, 동쪽에 있는 사이트의 개수 m이 입력으로 주어지면 mCn을 구하면 된다.

간단한 조합(Combination) 문제이다. 그런데 문제는 nCr은 n!/r!(n-r)!이기 때문에 분자를 분모로 나누기 전의 숫자는 너무 커질 수도 있다. 따라서 nCr과 nCn-r은 같다는 성질을 이용하면 된다.

10C2나 10C8은 같다. 10C8보다는 10C2를 하는 것이 훨씬 효율적이다.

따라서 처음에 입력을 받고 r = min(r, n - r);로 r을 줄여주었다.

#include <iostream>
using namespace std;

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int t;
	cin >> t;
	for (int i = 0; i < t; i++) {
		int r, n;
		cin >> r >> n;
		r = min(r, n - r);
		long long numerator = 1;
		long long denominator = 1;
		for (int i = n; i > n - r; i--) {
			numerator *= i;
		}
		for (int i = r; i >= 1; i--) {
			denominator *= i;
		}
		cout << numerator / denominator << '\n';
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1037번 약수  (0) 2020.02.07
[백준] 1094번 막대기  (0) 2020.02.07
[백준] 1026번 보물  (0) 2020.02.07
[백준] 4963번 섬의 개수  (0) 2020.02.06
[백준] 1912번 연속합  (0) 2020.02.06
728x90
 

1026번: 보물

첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거나 같은 음이 아닌 정수이다.

www.acmicpc.net

B는 재배열하면 안 된다고 써있지만 A를 자유롭게 재배열하면 B를 재배열하는 것과 같기 때문에 B를 재배열해도 상관없다.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool cmp(int x, int y) {
	return x > y;
}

int main() {
	int n;
	cin >> n;
	vector<int> a(n);
	vector<int> b(n);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> b[i];
	}
	sort(a.begin(), a.end());
	sort(b.begin(), b.end(), cmp);
	int sum = 0;
	for (int i = 0; i < n; i++) {
		sum += (a[i] * b[i]);
	}
	cout << sum;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1094번 막대기  (0) 2020.02.07
[백준] 1010번 다리 놓기  (0) 2020.02.07
[백준] 4963번 섬의 개수  (0) 2020.02.06
[백준] 1912번 연속합  (0) 2020.02.06
[백준] 2656번 전깃줄  (0) 2020.02.06
728x90
 

4963번: 섬의 개수

문제 정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오. 한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.  두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러쌓여 있으며, 지도 밖으로 나갈 수 없다. 입력 입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는

www.acmicpc.net

왼쪽 오른쪽 위 아래 뿐만 아니라 대각선까지 되는 DFS, BFS 문제는 처음 봤다. 하지만 푸는 방법은 똑같으니 쉽게 풀 수 있었다.

#include <iostream> 
#include <vector> 
#include <queue> 
#include <tuple>
#include <algorithm>
using namespace std;

int main() {
	while (true) {
		int w, h;
		cin >> w >> h;
		if (w == 0 && h == 0) break;
		vector<vector<int>> v(h);
		vector<vector<bool>> visited(h);
		for (int i = 0; i < h; i++) {
			v[i] = vector<int>(w);
			visited[i] = vector<bool>(w);
		}
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> v[i][j];
			}
		}
		int count = 0;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				if (v[i][j] == 1 && !visited[i][j]) {
					count++;
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < h && cur.second + 1 < w && !visited[cur.first + 1][cur.second + 1] && v[cur.first + 1][cur.second + 1] == 1) {
								q.push(make_pair(cur.first + 1, cur.second + 1));
							}
							if (cur.first + 1 < h && cur.second - 1 >= 0 && !visited[cur.first + 1][cur.second - 1] && v[cur.first + 1][cur.second - 1] == 1) {
								q.push(make_pair(cur.first + 1, cur.second - 1));
							}
							if (cur.first - 1 >= 0 && cur.second + 1 < w && !visited[cur.first - 1][cur.second + 1] && v[cur.first - 1][cur.second + 1] == 1) {
								q.push(make_pair(cur.first - 1, cur.second + 1));
							}
							if (cur.first - 1 >= 0 && cur.second - 1 >= 0 && !visited[cur.first - 1][cur.second - 1] && v[cur.first - 1][cur.second - 1] == 1) {
								q.push(make_pair(cur.first - 1, cur.second - 1));
							}
							if (cur.first + 1 < h && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 1) {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 1) {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < w && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 1) {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 1) {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
			}
		}
		cout << count << endl;
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1010번 다리 놓기  (0) 2020.02.07
[백준] 1026번 보물  (0) 2020.02.07
[백준] 1912번 연속합  (0) 2020.02.06
[백준] 2656번 전깃줄  (0) 2020.02.06
[백준] 11054번 가장 긴 바이토닉 부분 수열  (0) 2020.02.06
728x90
 

1912번: 연속합

첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.

www.acmicpc.net

#include <iostream> 
#include <vector> 
#include <queue> 
#include <tuple>
#include <algorithm>
using namespace std;

int main() {
	cin.tie(NULL);
	int n;
	cin >> n;
	vector<int> inputNumbers(n);
	for (int i = 0; i < n; i++) {
		cin >> inputNumbers[i];
	}
	vector<int> sum(n);
	int maxSum = inputNumbers[0];
	sum[0] = inputNumbers[0];
	for (int i = 1; i < n; i++) {
		if (sum[i - 1] + inputNumbers[i] > inputNumbers[i])
			sum[i] = sum[i - 1] + inputNumbers[i];
		else 
			sum[i] = inputNumbers[i];
		if (sum[i] > maxSum) maxSum = sum[i];
	}
	cout << maxSum;
	return 0;
}

 

입력이 다음과 같이 들어왔을 때의 예를 살펴보자.

8
3 5 -3 2 2 -33 7 3 

앞에서부터 차례로 연속합을 구해서 i까지의 최대 연속 합을 sum[i]에 저장하고 최대 연속합이 나올 때마다 maxSum을 갱신하기로 하자.

양수를 더하면 항상 이득이기때문에 양수일 때에는 sum을 갱신한다.

sum[0] = 3, maxSum = 3

sum[1] = 8, maxSum = 8 이 된다.

하지만 그렇다고 음수인 -3을 더하면 sum[2]가 5로 줄어드니 새로 더해야 할까? 여기에서 멈춰야 할까?

계속 더하면

sum[2] = 5, maxSum = 8

sum[3] = 7, maxSum = 7

sum[4] = 9, maxSum = 9

이렇게 9를 얻을 수 있는데 새로 더하거나 멈추면 9를 놓치게 된다.

그럼 일단 음수가 나와도 계속 더하는 것으로 해보자.

sum[5] = -24, maxSum = 9

sum[6] = -17, maxSum = 9

sum[7] = -14, maxSum = 9

답은 maxSum인 9일까?

마지막에 7 3을 더하면 10이 나와서 정답은 10인데 9로 틀린 답을 내게 된다.

그럼 어떻게 했어야 할까?

-33까지 더하면 max[5] = -24, maxSum = 9이다.

그 다음 7이 나왔을 때 7부터 아예 새로 더하면 7이 될 것을 앞에서 구한 것을 굳이 연속해서 더해서 -17부터 시작할 필요는 없다. 부모가 빚을 물려준다면 아예 파산 신청을 하고 새로 시작하는 게 나은 것처럼 아예 7부터 새로 시작하도록 하자.

sum[6] = 7, maxSum = 9

sum[7] = 10, maxSum = 10

그러면 정답은 maxSum인 10이 된다.

 

그러면 언제 버리고 새로 시작해야 하는걸까?

앞에서 구한 연속 합에 나 자신을 더한 것보다 나 자신이 더 크다면 굳이 빚까지 상속받는 것보다는

나 자신부터 새로 시작하면 된다.

728x90
728x90
 

2565번: 전깃줄

첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결되는 위치의 번호가 차례로 주어진다. 위치의 번호는 500 이하의 자연수이고, 같은 위치에 두 개 이상의 전깃줄이 연결될 수 없다.

www.acmicpc.net

왼쪽 전봇대 번호를 기준으로 오름차순 정렬한 후 LIS를 구하고 총 전깃줄 개수에서 LIS를 빼주었다.

#include <iostream> 
#include <vector> 
#include <queue> 
#include <tuple>
#include <algorithm>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<pair<int, int>> line(n);
	for (int i = 0; i < n; i++) {
		int from, to;
		cin >> from >> to;
		line[i] = make_pair(from, to);
	}
	sort(line.begin(), line.end());
	vector<int> dp(n);
	dp[0] = 1;
	for (int i = 1; i < n; i++) {
		int maxLength = 0;
		for (int j = 0; j < i; j++) {
			if (line[i].second > line[j].second && dp[j] > maxLength)
				maxLength = dp[j];
		}
		dp[i] = maxLength + 1;
	}
	int lis = 0;
	for (int i = 0; i < n; i++) {
		if (dp[i] > lis) lis = dp[i];
	}
	cout << n - lis;
	return 0;
}
728x90
728x90

단계별로 풀어보기 동적계획법 1의 12단계 문제

 

11054번: 가장 긴 바이토닉 부분 수열

첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000)

www.acmicpc.net

LIS는 앞에서부터 구해서 increasingDp에 저장했고 LDS는 뒤에서부터 구해서 decreasingDp에 저장했다.

그리고 bitonicDp는 그 increasingDp[i]와 decreasingDp[i]를 더하고 i번째 수는 중복되어 세었으니 1을 빼주었다.

#include <iostream> 
#include <vector> 
#include <queue> 
#include <algorithm>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int>	v(n);
	for (int i = 0; i < n; i++) {
		cin >> v[i];
	}
	vector<int> increasingDp(n);
	vector<int> decreasingDp(n);
	increasingDp[0] = 1;
	for (int i = 1; i < n; i++) {
		int maxLength = 0;
		for (int j = 0; j < i; j++) {
			if (v[j] < v[i] && increasingDp[j] > maxLength) {
				maxLength = increasingDp[j];
			}
		}
		increasingDp[i] = maxLength + 1;
	}
	decreasingDp[n - 1] = 1;
	for (int i = n - 1; i >= 0; i--) {
		int maxLength = 0;
		for (int j = n - 1; j > i; j--) {
			if (v[i] > v[j] && decreasingDp[j] > maxLength) {
				maxLength = decreasingDp[j];
			}
		}
		decreasingDp[i] = maxLength + 1;
	}
	vector<int> bitonicDp(n);
	for (int i = 0; i < n; i++) {
		bitonicDp[i] = increasingDp[i] + decreasingDp[i] - 1;
	}
	int maxDp = 0;
	for (int i = 0; i < n; i++) {
		if (bitonicDp[i] > maxDp) maxDp = bitonicDp[i];
	}
	cout << maxDp;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1912번 연속합  (0) 2020.02.06
[백준] 2656번 전깃줄  (0) 2020.02.06
[백준] 11651번 좌표 정렬하기 2  (0) 2020.02.06
[백준] 2583번 영역 구하기  (0) 2020.02.06
[백준] 2468번 안전영역  (0) 2020.02.06
728x90
 

11651번: 좌표 정렬하기 2

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

Java로 풀어보고 C++로도 풀어봤다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        ArrayList<Loc> list = new ArrayList<>();
        for(int i = 0; i < n; i++) {
            list.add(new Loc(in.nextInt(), in.nextInt()));
        }
        Collections.sort(list, new Comparator<Loc>() {
            @Override
            public int compare(Loc o1, Loc o2) {
                if(o1.y == o2.y)
                    return o1.x - o2.x;
                else
                    return o1.y - o2.y;
            }
        });
        for(Loc i : list)
            System.out.println(i);
    }
}
class Loc{
    int x;
    int y;

    public Loc(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return x + " " + y;
    }
}
#include <iostream> 
#include <vector> 
#include <queue> 
#include <algorithm>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<pair<int, int>> v;
	for (int i = 0; i < n; i++) {
		int x, y;
		cin >> x >> y;
		v.push_back(make_pair(y, x));
	}
	sort(v.begin(), v.end());
	for (pair<int, int> p : v) {
		cout << p.second << " " << p.first << '\n';
	}
	return 0;
}

 

pair는 첫 번째 원소(first)를 기준으로 오름차순 정렬, first가 같으면 두 번째 원소(second)를 기준으로 오름차순 정렬

728x90
728x90
 

2583번: 영역 구하기

첫째 줄에 M과 N, 그리고 K가 빈칸을 사이에 두고 차례로 주어진다. M, N, K는 모두 100 이하의 자연수이다. 둘째 줄부터 K개의 줄에는 한 줄에 하나씩 직사각형의 왼쪽 아래 꼭짓점의 x, y좌표값과 오른쪽 위 꼭짓점의 x, y좌표값이 빈칸을 사이에 두고 차례로 주어진다. 모눈종이의 왼쪽 아래 꼭짓점의 좌표는 (0,0)이고, 오른쪽 위 꼭짓점의 좌표는(N,M)이다. 입력되는 K개의 직사각형들이 모눈종이 전체를 채우는 경우는 없다.

www.acmicpc.net

BFS로 풀었다.

#include <iostream> 
#include <vector> 
#include <queue> 
#include <algorithm>
using namespace std;

int n;
vector<int> countAll;
vector<int> allArea;

int main() {
	int m, n, k;
	cin >> m >> n >> k;
	vector<vector<int>> v(m);
	for (int i = 0; i < m; i++) 
		v[i] = vector<int>(n);
	for (int i = 0; i < k; i++) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		for (int x = x1; x < x2; x++) {
			for (int y = y1; y < y2; y++) {
				v[y][x] = 1;
			}
		}
	}
	vector<vector<bool>> visited(m);
	for (int i = 0; i < m; i++)
		visited[i] = vector<bool>(n);
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (v[i][j] == 0 && !visited[i][j]) {
				queue < pair<int, int>> q;
				q.push(make_pair(i, j));
				int area = 0;
				while (!q.empty()) {
					pair<int, int> cur = q.front();
					q.pop();
					if (!visited[cur.first][cur.second] && v[cur.first][cur.second] == 0) {
						visited[cur.first][cur.second] = true;
						area++;
						if (cur.first + 1 < m && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 0) {
							q.push(make_pair(cur.first + 1, cur.second));
						}
						if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 0) {
							q.push(make_pair(cur.first - 1, cur.second));
						}
						if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 0) {
							q.push(make_pair(cur.first, cur.second + 1));
						}
						if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 0) {
							q.push(make_pair(cur.first, cur.second - 1));
						}
					}
				}
				allArea.push_back(area);
			}
		}
	}
	cout << allArea.size() << endl;
	sort(allArea.begin(), allArea.end());
	for (int i = 0; i < allArea.size(); i++) {
		cout << allArea[i] << " ";
	}
	return 0;
}
728x90
728x90
 

2468번: 안전 영역

재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는 안전한 영역이 최대로 몇 개가 만들어 지는 지를 조사하려고 한다. 이때, 문제를 간단하게 하기 위하여, 장마철에 내리는 비의 양에 따라 일정한 높이 이하의 모든 지점은 물에 잠긴다고 가정한다. 어떤 지역의 높이 정보는 행과 열의 크기가 각각 N인 2차원 배열 형태로 주어

www.acmicpc.net

BFS로 풀었다.

#include <iostream> 
#include <vector> 
#include <queue> 
#include <algorithm>
using namespace std;

int n;
vector<int> countAll;

int main() {
	countAll.push_back(1);
	cin >> n;
	vector<vector<int>> height(n);
	vector<vector<int>> rain(n);
	for (int i = 0; i < n; i++) {
		height[i] = vector<int>(n);
		rain[i] = vector<int>(n);
	}
	int maxHeight = 0;
	int minHeight = 101;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> height[i][j];
			if (height[i][j] > maxHeight) maxHeight = height[i][j];
			if (height[i][j] < minHeight) minHeight = height[i][j];
		}
	}
	for (int rainAmount = minHeight; rainAmount <= maxHeight; rainAmount++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (height[i][j] <= rainAmount) {
					rain[i][j] = 1;
				}
			}
		}

		int count = 0;
		vector<vector<bool>> visited(n);
		for (int i = 0; i < n; i++) {
			visited[i] = vector<bool>(n);
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (!visited[i][j] && rain[i][j] == 0) {
					count++;
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < n && !visited[cur.first + 1][cur.second] && rain[cur.first + 1][cur.second] == 0) {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && rain[cur.first - 1][cur.second] == 0) {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && rain[cur.first][cur.second + 1] == 0) {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && rain[cur.first][cur.second - 1] == 0) {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
			}
		}
		countAll.push_back(count);
	}
	int maxCount = 0;
	for (int i : countAll)
		if (i > maxCount) maxCount = i;
	cout << maxCount;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 11651번 좌표 정렬하기 2  (0) 2020.02.06
[백준] 2583번 영역 구하기  (0) 2020.02.06
[백준] 10026번 적록색약  (0) 2020.02.06
[백준] 4153번 직각삼각형  (0) 2020.02.05
[백준] 3009번 네 번째 점  (0) 2020.02.05
728x90
 

10026번: 적록색약

문제 적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다. 크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림이 있다. 그림은 몇 개의 구역으로 나뉘어져 있는데, 구역은 같은 색으로 이루어져 있다. 또, 같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다. (색상의 차이를 거의 느끼지 못하는 경우도 같은

www.acmicpc.net

BFS로 풀었다.

#include <iostream> 
#include <vector> 
#include <queue> 
using namespace std;

int n;

int main() {
	cin >> n;
	vector<vector<char>> v(n);
	vector<vector<bool>> visited(n);
	for (int i = 0; i < n; i++) {
		v[i] = vector<char>(n);
		visited[i] = vector<bool>(n);
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> v[i][j];
		}
	}
	int normalCount = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (!visited[i][j]) {
				normalCount++;
				if (v[i][j] == 'R') {
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < n && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 'R') {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 'R') {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 'R') {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 'R') {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
				else if (v[i][j] == 'G') {
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < n && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 'G') {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 'G') {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 'G') {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 'G') {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
				else if (v[i][j] == 'B') {
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < n && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 'B') {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 'B') {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 'B') {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 'B') {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			visited[i][j] = false;
			if (v[i][j] == 'G')
				v[i][j] = 'R';
		}
	}
	int abnormalCount = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (!visited[i][j]) {
				abnormalCount++;
				if (v[i][j] == 'R') {
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < n && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 'R') {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 'R') {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 'R') {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 'R') {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
				else if (v[i][j] == 'B') {
					queue<pair<int, int>> q;
					q.push(make_pair(i, j));
					while (!q.empty()) {
						pair<int, int> cur = q.front();
						q.pop();
						if (!visited[cur.first][cur.second]) {
							visited[cur.first][cur.second] = true;
							if (cur.first + 1 < n && !visited[cur.first + 1][cur.second] && v[cur.first + 1][cur.second] == 'B') {
								q.push(make_pair(cur.first + 1, cur.second));
							}
							if (cur.first - 1 >= 0 && !visited[cur.first - 1][cur.second] && v[cur.first - 1][cur.second] == 'B') {
								q.push(make_pair(cur.first - 1, cur.second));
							}
							if (cur.second + 1 < n && !visited[cur.first][cur.second + 1] && v[cur.first][cur.second + 1] == 'B') {
								q.push(make_pair(cur.first, cur.second + 1));
							}
							if (cur.second - 1 >= 0 && !visited[cur.first][cur.second - 1] && v[cur.first][cur.second - 1] == 'B') {
								q.push(make_pair(cur.first, cur.second - 1));
							}
						}
					}
				}
			}
		}
	}
	cout << normalCount << endl;
	cout << abnormalCount << endl;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2583번 영역 구하기  (0) 2020.02.06
[백준] 2468번 안전영역  (0) 2020.02.06
[백준] 4153번 직각삼각형  (0) 2020.02.05
[백준] 3009번 네 번째 점  (0) 2020.02.05
[백준] 10845번 큐  (0) 2020.02.05

+ Recent posts