※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 1058번 문제인 친구이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/1058 

 

1058번: 친구

지민이는 세계에서 가장 유명한 사람이 누구인지 궁금해졌다. 가장 유명한 사람을 구하는 방법은 각 사람의 2-친구를 구하면 된다. 어떤 사람 A가 또다른 사람 B의 2-친구가 되기 위해선, 두 사람

www.acmicpc.net

각 사람을 노드로, 노드 사이의 에지를 서로 친구관계이면 가중치 1, 아니라면 가중치 무한대인 그래프에서 각 사람끼리의 거리를 구해 거리가 1 또는 2인 사람들을 찾는 것으로 문제를 해결할 수 있다.

 

이를 알아낼 수 있는 방법 중 하나는 Floyd-Warshall 알고리즘을 이용하는 것이다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
using namespace std;

int dist[50][50];

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

	int N; cin >> N;
	for (int i = 0; i < N; i++) {
		string s; cin >> s;
		for (int j = 0; j < N; j++) {
			if (i == j) dist[i][j] = 0;
			else if (s[j] == 'N') dist[i][j] = 999;
			else dist[i][j] = 1;
		}
	}

	//Floyd-Warshall
	for (int k = 0; k < N; k++) {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (dist[i][j] > dist[i][k] + dist[k][j]) dist[i][j] = dist[i][k] + dist[k][j];
			}
		}
	}
	int ans = 0;
	for (int i = 0; i < N; i++) {
		int cnt = 0;
		for (int j = 0; j < N; j++) {
			if (0 < dist[i][j] && dist[i][j] < 3) cnt++;
		}
		if (cnt > ans) ans = cnt;
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 5721 // C++] 사탕 줍기 대회  (0) 2021.09.21
[BOJ 22865 // C++] 가장 먼 곳  (0) 2021.09.20
[BOJ 2661 // C++] 좋은수열  (0) 2021.09.18
[BOJ 14891 // C++] 톱니바퀴  (0) 2021.09.17
[BOJ 13904 // C++] 과제  (0) 2021.09.16

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2661번 문제인 좋은수열이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/2661 

 

2661번: 좋은수열

첫 번째 줄에 1, 2, 3으로만 이루어져 있는 길이가 N인 좋은 수열들 중에서 가장 작은 수를 나타내는 수열만 출력한다. 수열을 이루는 1, 2, 3들 사이에는 빈칸을 두지 않는다.

www.acmicpc.net

수열을 문자열을 이용하여 나타내고, substr 함수를 이용하여 문제의 조건을 확인해줄 수 있다.

숫자를 붙여나가는 과정을 1, 2, 3의 순서대로 붙여나간다면 사전순으로 가장 빠른 가장 긴 문자열을 알아낼 수 있다.

물론 숫자를 붙여나가다가 "나쁜 수열"을 만난다면 그 이후는 더 탐색할 필요가 없으므로 되돌아나오자.

 

개수가 80개로 전체를 탐색하기에는 나올 수 있는 경우의 수가 너무 많지만(3^80), "나쁜 수열"의 비중이 매우 높아 가지치기가 매우 잘 되므로 수열 자체는 빠르게 얻어낼 수 있다.

 

물어볼 수 있는 개수가 80개 뿐이므로, 글쓴이는 답이 될 80개의 문자열을 코드를 이용하여 뽑아내고 이를 이용하여 O(1)에 답을 하는 코드를 제출하였다.

 

아래는 답의 배열을 뽑아내기 위한 전처리 코드이다. 이 코드 자체는 원하는 결과를 모두 찾은 뒤 탐색을 종료하는 구현이 되어있지 않으므로 동작시간이 오래 걸린다는 점을 유의하자. 또한, 아래 코드는 출력된 값의 마지막 항 뒤에 ','가 같이 출력하고 0번째 항은 생략하고 있는 점을 유의하자.

#include <iostream>
#include <string>
using namespace std;

bool done[81];
string ans[81];
string s = "";

void func(int current) {
	for (int k = 1; k <= 3; k++) {
		s += to_string(k);
		bool chk = 1;
		for (int i = 1; i * 2 <= current; i++) {
			if (s.substr(current - i, i) == s.substr(current - 2 * i, i)) chk = 0;
		}
		if (chk) {
			if (!done[current]) {
				done[current] = 1;
				ans[current] = s;
				if (current == 80) {
					cout << '{';
					for (int i = 1; i <= 80; i++) cout << '"' << ans[i] << "\", ";
					cout << '}';
				}
			}
			if (current!=80) func(current + 1);
		}
		s.pop_back();
	}
}

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

	func(1);
}

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
using namespace std;

string ans[81] = { "", "1", "12", "121", "1213", "12131", "121312", "1213121", "12131231", "121312313", "1213123132", "12131231321", "121312313212", "1213123132123", "12131231321231", "121312313212312", "1213123132123121", "12131231321231213", "121312313212312131", "1213123132123121312", "12131231321231213123", "121312313212312131231", "1213123132123121312313", "12131231321231213123132", "121312313212312131231321", "1213123132123121312313212", "12131231321231213123132131", "121312313212312131231321312", "1213123132123121312313213121", "12131231321231213123132131213", "121312313212312131231321312132", "1213123132123121312313213121321", "12131231321231213123132131213212", "121312313212312131231321312132123", "1213123132123121312313213121321231", "12131231321231213123132131213212312", "121312313212312131231321312132123121", "1213123132123121312313213121321231213", "12131231321231213123132131213212312131", "121312313212312131231321312132123121312", "1213123132123121312313213121321231213123", "12131231321231213123132131213212312131231", "121312313212312131231321312132123121312313", "1213123132123121312313213121321231213123132", "12131231321231213123132131213212312131231321", "121312313212312131231321312132123121312313212", "1213123132123121312313213121321231213123132123", "12131231321231213123132131213212312131231321231", "121312313212312131231321312132123121312313212312", "1213123132123121312313213121321231213123132123121", "12131231321231213123132131213212312131231321231213", "121312313212312131231321312132123121312313212312131", "1213123132123121312313213121321231213123132123121312", "12131231321231213123132131213212312131231321231213212", "121312313212312131231321312132123121312313212312132123", "1213123132123121312313213121321231213123132123121321231", "12131231321231213123132131213212312131231321231213212313", "121312313212312131231321312132123121312313212312132123132", "1213123132123121312313213121321231213123132123121321231321", "12131231321231213123132131213212312131231321231213212313212", "121312313212312131231321312132123121312313212312132123132131", "1213123132123121312313213121321231213123132123121321231321312", "12131231321231213123132131213212312131231321231213212313213121", "121312313212312131231321312132123121312313212312132123132131213", "1213123132123121312313213121321231213123132123121321231321312132", "12131231321231213123132131213212312131231321231213212313213121321", "121312313212312131231321312132123121312313212312132123132131213212", "1213123132123121312313213121321231213123132123121321231321312132123", "12131231321231213123132131213212312131231321231213212313213121321231", "121312313212312131231321312132123121312313212312132123132131213212312", "1213123132123121312313213121321231213123132123121321231321312132123121", "12131231321231213123132131213212312131231321231213212313213121321231213", "121312313212312131231321312132123121312313212312132123132131213212312131", "1213123132123121312313213121321231213123132123121321231321312132123121312", "12131231321231213123132131213212312131231321231213212313213121321231213123", "121312313212312131231321312132123121312313212312132123132131213212312131231", "1213123132123121312313213121321231213123132123121321231321312132123121312313", "12131231321231213123132131213212312131231321231213212313213121321231213123132", "121312313212312131231321312132123121312313212312132123132131213212312131231321", "1213123132123121312313213121321231213123132123121321231321312132123121312313212", "12131231321231213123132131213212312131231321231213212313213121321231213123132123" };

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

	int N; cin >> N;
	cout << ans[N];
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 22865 // C++] 가장 먼 곳  (0) 2021.09.20
[BOJ 1058 // C++] 친구  (0) 2021.09.19
[BOJ 14891 // C++] 톱니바퀴  (0) 2021.09.17
[BOJ 13904 // C++] 과제  (0) 2021.09.16
[BOJ 3109 // C++] 빵집  (0) 2021.09.15

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 14891번 문제인 톱니바퀴이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/14891 

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

톱니바퀴의 개수와 조작횟수가 적으므로 문제에서 주어진 톱니바퀴의 회전을 그대로 구현하는 것으로 문제를 해결할 수 있다.

 

글쓴이는 미리 주어진 톱니바퀴의 왼쪽과 오른쪽을 하나하나 차례로 살피면서 회전해야 할 톱니바퀴들을 미리 표기하고, 모두 표기한 다음에 회전시킬 톱니바퀴들만 방향에 맞춰 회전시키는 방식으로 코드를 구현하였다.

 

톱니바퀴의 회전은 문자열을 잘라 붙이는 것으로 해결했다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int rot[6];
string gear[6];

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

	gear[0] = gear[5] = "99999999";
	for (int i = 1; i <= 4; i++) cin >> gear[i];

	int T; cin >> T;
	while (T--) {
		memset(rot, 0, sizeof(rot));
		int x, r; cin >> x >> r;
		rot[x] = r;
		int rr = r * -1, idx = x - 1;
		if (idx > 0) {
			while ((int)gear[idx][2] + (int)gear[idx + 1][6] == (int)'0' + (int)'1') {
				rot[idx--] = rr;
				rr *= -1;
			}
		}
		rr = r * -1, idx = x + 1;
		if (idx < 5) {
			while ((int)gear[idx - 1][2] + (int)gear[idx][6] == (int)'0' + (int)'1') {
				rot[idx++] = rr;
				rr *= -1;
			}
		}
		for (int i = 1; i < 5; i++) {
			if (rot[i] == 1) {
				gear[i] = gear[i].substr(7, 1) + gear[i].substr(0, 7);
			}
			else if (rot[i] == -1) gear[i] = gear[i].substr(1, 7) + gear[i].substr(0, 1);
		}
	}
	int ans = 0;
	if (gear[1][0] == '1') ans += 1;
	if (gear[2][0] == '1') ans += 2;
	if (gear[3][0] == '1') ans += 4;
	if (gear[4][0] == '1') ans += 8;

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1058 // C++] 친구  (0) 2021.09.19
[BOJ 2661 // C++] 좋은수열  (0) 2021.09.18
[BOJ 13904 // C++] 과제  (0) 2021.09.16
[BOJ 3109 // C++] 빵집  (0) 2021.09.15
[BOJ 19598 // C++] 최소 회의실 개수  (0) 2021.09.14

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 13904번 문제인 과제이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/13904 

 

13904번: 과제

예제에서 다섯 번째, 네 번째, 두 번째, 첫 번째, 일곱 번째 과제 순으로 수행하고, 세 번째, 여섯 번째 과제를 포기하면 185점을 얻을 수 있다.

www.acmicpc.net

greedy 알고리즘 문제이다.

과제를 수행하는 날짜를 뒷날짜부터 살펴보며, 그날 수행할 수 있는 가장 점수가 높은 과제를 수행하는 것이 최적이 된다. 증명은 귀류법으로 간단히 할 수 있다.

 

우선순위 큐(priority queue)를 이용하면 현재 날짜에 수행할 수 있는 가장 점수가 높은 과제가 무엇인지를 쉽게 관리할 수 있다.

 

아래는 제출한 소스코드이다.

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

queue<int> que[1001];
priority_queue<int> pq;

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

	int ans = 0;

	int N; cin >> N;
	while (N--) {
		int d, w; cin >> d >> w;
		que[d].push(w);
	}

	for (int i = 1000; i > 0; i--) {
		while (!que[i].empty()) {
			pq.push(que[i].front());
			que[i].pop();
		}
		if (!pq.empty()) {
			ans += pq.top();
			pq.pop();
		}
	}

	cout << ans;
}

 

728x90

'BOJ' 카테고리의 다른 글

[BOJ 2661 // C++] 좋은수열  (0) 2021.09.18
[BOJ 14891 // C++] 톱니바퀴  (0) 2021.09.17
[BOJ 3109 // C++] 빵집  (0) 2021.09.15
[BOJ 19598 // C++] 최소 회의실 개수  (0) 2021.09.14
[BOJ 14419 // C++] Foehn Phenomena  (0) 2021.09.13

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 3109번 문제인 빵집이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/3109 

 

3109번: 빵집

유명한 제빵사 김원웅은 빵집을 운영하고 있다. 원웅이의 빵집은 글로벌 재정 위기를 피해가지 못했고, 결국 심각한 재정 위기에 빠졌다. 원웅이는 지출을 줄이고자 여기저기 지출을 살펴보던

www.acmicpc.net

주어지는 지형에서 가장 왼쪽 열에서 오른쪽 열까지 이을 수 있는 파이프의 개수를 세는 문제이다.

 

이 문제는 왼쪽 열의 가장 위칸서부터 출발하여 오른쪽 열로 도달할 수 있는지를 확인하면서 방문한 칸을 다시 방문하지 못하게 처리하는 것으로 문제를 해결할 수 있다.

 

이러한 방식이 통하는 이유는 각 칸을 이번 시도에 방문하여 오른쪽 열에 도달할 수 없다면 다른 시도에서 다시 방문하더라도 오른쪽 끝으로 갈 수 없기 때문이다. (또한, 도달했다면 모든 파이프가 지나는 칸은 달라야한다는 조건에 따라 해당 칸을 다시 이용할 수 없고, 가장 위칸서부터 출발한 이 경로로 이동하면 같은 칸을 경유하는 다른 경로에 비해 존재할 수 있는 다른 가능한 가능성을 배제하지 않는다는 점을 생각하자.)

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
using namespace std;

int R, C;
string field[10002];

int dfs(int r, int c) {
	if (c == C - 1) return 1;
	if (field[r - 1][c + 1] == '.') {
		field[r - 1][c + 1] = 'x';
		if (dfs(r - 1, c + 1)) return 1;
	}
	if (field[r][c + 1] == '.') {
		field[r][c + 1] = 'x';
		if (dfs(r, c + 1)) return 1;
	}
	if (field[r + 1][c + 1] == '.') {
		field[r + 1][c + 1] = 'x';
		if (dfs(r + 1, c + 1)) return 1;
	}

	return 0;
}

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

	cin >> R >> C;
	for (int c = 0; c < C; c++) field[0] += 'x';
	for (int c = 0; c < C; c++) field[R + 1] += 'x';
	for (int r = 1; r <= R; r++) cin >> field[r];

	int ans = 0;
	for (int r = 1; r <= R; r++) {
		ans += dfs(r, 0);
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 14891 // C++] 톱니바퀴  (0) 2021.09.17
[BOJ 13904 // C++] 과제  (0) 2021.09.16
[BOJ 19598 // C++] 최소 회의실 개수  (0) 2021.09.14
[BOJ 14419 // C++] Foehn Phenomena  (0) 2021.09.13
[BOJ 8986 // C++] 전봇대  (0) 2021.09.12

※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 19598번 문제인 최소 회의실 개수이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/19598 

 

19598번: 최소 회의실 개수

서준이는 아빠로부터 N개의 회의를 모두 진행할 수 있는 최소 회의실 개수를 구하라는 미션을 받았다. 각 회의는 시작 시간과 끝나는 시간이 주어지고 한 회의실에서 동시에 두 개 이상의 회의

www.acmicpc.net

빌려야 하는 회의실의 개수는 같은 시간에 진행되고 있는 회의개수의 최댓값과 같다.

 

따라서, 시간의 흐름에 따라 주어진 회의시간의 시작과 끝을 정렬하고, 각 시작과 끝마다 회의의 개수를 더하고 빼는 것으로 각 시각에 진행되고 있는 회의 개수의 최댓값을 구하는 것으로 문제를 해결할 수 있다.

 

회의가 끝나는 것을 시작하는 것보다 먼저 처리해야하는 점에 유의하여 구현하자. (문제의 예제입력 2)

 

아래는 제출한 소스코드이다.

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

pair<int,int> arr[200000];

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

	int N; cin >> N;
	for (int i = 0; i < N; i++) {
		int L, R; cin >> L >> R;
		arr[i] = { L,1 }, arr[N + i] = { R,-1 };
	}

	sort(arr, arr + 2 * N);

	int ans = 0;
	int cnt = 0;
	for (int i = 0; i < 2 * N; i++) {
		cnt += arr[i].second;
		if (cnt > ans) ans = cnt;
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 13904 // C++] 과제  (0) 2021.09.16
[BOJ 3109 // C++] 빵집  (0) 2021.09.15
[BOJ 14419 // C++] Foehn Phenomena  (0) 2021.09.13
[BOJ 8986 // C++] 전봇대  (0) 2021.09.12
[BOJ 15809 // C++] 전국시대  (0) 2021.09.11

+ Recent posts