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

 

이번에 볼 문제는 백준 1339번 문제인 단어 수학이다.
문제는 아래 링크를 확인하자.

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

 

1339번: 단어 수학

첫째 줄에 단어의 개수 N(1 ≤ N ≤ 10)이 주어진다. 둘째 줄부터 N개의 줄에 단어가 한 줄에 하나씩 주어진다. 단어는 알파벳 대문자로만 이루어져있다. 모든 단어에 포함되어 있는 알파벳은 최대

www.acmicpc.net

복면산 문제이다.

숫자 ABC는 100*A + 10*B + C와 같이 나타낼 수 있다. 이와 같이 각 문자가 총합에 얼마나 들어있는지를 계산하고, 가장 많이 들어있는 문자부터 9에서 0까지의 숫자를 넣어 주어진 식의 최댓값을 구할 수 있다.

 

A부터 Z까지의 모든 문자가 들어올 수 있음에 주의하자.

 

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

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;

ll cnt[26];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int N; cin >> N;
	for (int i = 0; i < N; i++) {
		ll digit = 1;
		string s; cin >> s;
		for (auto iter = s.rbegin(); iter != s.rend(); iter++) {
			cnt[*iter - 'A'] += digit;
			digit *= 10;
		}
	}

	sort(cnt, cnt + 26);

	ll ans = 0;
	for (ll i = 16; i < 26; i++) {
		ans += cnt[i] * (i - 16);
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1969 // C++] DNA  (0) 2021.08.16
[BOJ 20136 // C++] 멀티탭 스케줄링 2  (0) 2021.08.15
[BOJ 1080 // C++] 행렬  (0) 2021.08.13
[BOJ 15892 // C++] 사탕 줍는 로봇  (0) 2021.08.12
[BOJ 3013 // C++] 부분 수열의 중앙값  (0) 2021.08.11

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

 

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

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

 

1080번: 행렬

첫째 줄에 행렬의 크기 N M이 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 행렬 A가 주어지고, 그 다음줄부터 N개의 줄에는 행렬 B가 주어진다.

www.acmicpc.net

다음과 같은 관찰을 통하여 문제를 해결하자.

"A의 맨 왼쪽 위칸의 숫자와 B의 맨 왼쪽 위칸의 숫자가 다르다면, 이것을 같게 하려면 어떻게 해야할까?"

"그러면 그 오른쪽 칸은? 그 칸을 확인하고 나면 그 오른쪽 칸은?"

 

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

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

string A[50];
string B[50];

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

	int cnt = 0;
	int R, C; cin >> R >> C;
	for (int r = 0; r < R; r++) cin >> A[r];
	for (int r = 0; r < R; r++) cin >> B[r];
	for (int r = 2; r < R; r++) {
		for (int c = 2; c < C; c++) {
			if (A[r - 2][c - 2] != B[r - 2][c - 2]) {
				cnt++;
				for (int rr = r - 2; rr <= r; rr++) {
					for (int cc = c - 2; cc <= c; cc++) {
						if (A[rr][cc] == '0') A[rr][cc] = '1';
						else A[rr][cc] = '0';
					}
				}
			}
		}
	}

	bool chk = 1;
	for (int r = 0; r < R; r++) {
		for (int c = 0; c < C; c++) {
			if (A[r][c] != B[r][c]) chk = 0;
		}
	}

	if (chk) cout << cnt;
	else cout << -1;
}
728x90

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

 

이번에 볼 문제는 백준 15892번 문제인 사탕 줍는 로봇이다.
문제는 아래 링크를 확인하자.

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

 

15892번: 사탕 줍는 로봇

첫 번째 줄에 성원이네 집안에 있는 방의 개수를 나타내는 자연수 n(2 ≤ n ≤ 300)과 복도의 개수를 나타내는 자연수 m(1 ≤ m ≤ 5,000)이 공백으로 구분되어 주어진다. 두 번째 줄부터 m개의 줄에

www.acmicpc.net

이 문제는 각 방을 노드로, 복도의 사탕의 개수를 가중치로 하는 그래프로 나타냈을 때 1번 방과 N번 방을 각각 source와 sink로 하는 최대 유량을 구하는 것으로 풀 수 있다.

 

같은 한 쌍의 방을 둘 이상의 서로 다른 복도로 이을 수 있다는 점에 주의하자.

 

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

#define INF 1000000007
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

int source, sink;
int edge[301][301];
vector<int> G[301];
int level[301];

bool bfs() {
	memset(level, 0, sizeof(level));
	level[source] = 1;
	queue<int> que;
	que.push(source);

	while (!que.empty()) {
		int current = que.front(); que.pop();
		for (auto node : G[current]) {
			if (edge[current][node] && level[node] == 0) {
				level[node] = level[current] + 1;
				que.push(node);
			}
		}
	}
	return level[sink];
}

int turn[301];

int dfs(int current, int flow) {
	if (current == sink) return flow;
	int cursize = G[current].size();
	for (int& i = turn[current]; i < cursize; i++) {
		int node = G[current][i];
		if (edge[current][node] && level[node] == level[current] + 1) {
			int f = dfs(node, min(edge[current][node], flow));
			if (f) {
				edge[current][node] -= f;
				edge[node][current] += f;
				return f;
			}
		}
	}
	return 0;
}

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

	int N, M; cin >> N >> M;
	source = 1, sink = N;

	while (M--) {
		int x, y, w; cin >> x >> y >> w;
		if (edge[x][y]) {
			edge[x][y] += w;
			edge[y][x] += w;
		}
		else {
			edge[x][y] = edge[y][x] = w;
			G[x].push_back(y);
			G[y].push_back(x);
		}
	}

	int flow = 0;

	while (bfs()) {
		memset(turn, 0, sizeof(turn));
		int f;
		while (f = dfs(source, INF)) flow += f;
	}

	cout << flow;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1339 // C++] 단어 수학  (0) 2021.08.14
[BOJ 1080 // C++] 행렬  (0) 2021.08.13
[BOJ 3013 // C++] 부분 수열의 중앙값  (0) 2021.08.11
[BOJ 5406 // C++] No Smoking, Please  (0) 2021.08.10
[BOJ 3000 // C++] 직각 삼각형  (0) 2021.08.09

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

 

이번에 볼 문제는 백준 3013번 문제인 부분 수열의 중앙값이다.
문제는 아래 링크를 확인하자.

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

 

3013번: 부분 수열의 중앙값

{4}, {7, 2, 4}, {5, 7, 2, 4, 3}, {5, 7, 2, 4, 3, 1, 6}

www.acmicpc.net

이 문제에서 부분수열이란 연속된 항들로 구성된 부분수열을 의미한다.

주어진 수열의 모든 수는 서로 다르므로, 홀수 길이의 부분수열들 가운데 중앙값이 B인 부분수열의 개수는 다음과 같은 관찰을 통해 계산할 수 있다.

 

1) 이 부분수열은 B보다 큰 수와 B보다 작은 수의 개수가 같은 개수로 구성되어야한다.

2) 부분수열은 B를 포함해야하므로 (시작~B의 앞에 적힌 숫자), B, (B의 뒤에 적힌 숫자) 와 같은 구성을 가진다.

 

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

#include <iostream>
using namespace std;
typedef long long ll;

int arr[100000];
int diff[200001];

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

	ll ans = 0;
	int N, B; cin >> N >> B;
	int idx;
	for (int i = 0; i < N; i++) {
		cin >> arr[i];
		if (arr[i] == B) idx = i;
	}
	
	int cnt = 1;
	
	for (int i = idx; i < N; i++) {
		if (arr[i] > B) cnt++;
		else cnt--;
		diff[100000 + cnt]++;
	}

	cnt = -1;
	
	for (int i = idx; i >= 0; i--) {
		if (arr[i] > B) cnt--;
		else cnt++;
		ans += diff[100000 + cnt];
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1080 // C++] 행렬  (0) 2021.08.13
[BOJ 15892 // C++] 사탕 줍는 로봇  (0) 2021.08.12
[BOJ 5406 // C++] No Smoking, Please  (0) 2021.08.10
[BOJ 3000 // C++] 직각 삼각형  (0) 2021.08.09
[BOJ 1256 // C++] 사전  (0) 2021.08.08

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

 

이번에 볼 문제는 백준 5406번 문제인 No Smoking, Please이다.
문제는 아래 링크를 확인하자.

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

 

5406번: No Smoking, Please

The new anti-smoking laws have been in effect for some time now, but some restaurant owners still have problems coping with the new rules. Some say that it is detrimental to their business, others are relieved that their clothes no longer smell of cigarett

www.acmicpc.net

레스토랑의 출입구와 주방을 각각 source와 sink로 두고 각 방들을 노드로, 두 방을 잇는 연결통로를 각 방에 해당하는 두 노드를 이으면서 가중치가 (해당 통로에 air lock과 hatch를 설치할 때 필요한 비용)인 에지로 모델링을 하여 minimal cut을 구하면 문제를 해결할 수 있다.

 

벽에는 hatch가 필요없다는 조건이 레스토랑 전체를 나타내는 전체 직사각형의 바깥둘레를 의미하는 것으로 잘못 해석하여 매우 많은 오답을 제출했다(...). (연결통로의 크기가 0이라면 통로가 없으니 벽으로 생각해야하는 듯하다.)

 

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

#define INF 1000000007
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

int R, C, RC;
int source, sink;
int edge[1000000][4];
vector<int> G[1000000];
int level[1000000];

bool bfs() {
	memset(level, 0, sizeof(level));
	level[source] = 1;
	queue<int> que;
	que.push(source);

	while(!que.empty()) {
		int current = que.front(); que.pop();
		for (auto node : G[current]) {
			int n;
			if (node == 0) n = current - C;
			else if (node == 1) n = current + C;
			else if (node == 2) n = current - 1;
			else n = current + 1;
			if (edge[current][node] && level[n] == 0) {
				level[n] = level[current] + 1;
				que.push(n);
			}
		}
	}

	return level[sink];
}

int turn[1000000];

int dfs(int current, int flow) {
	if (current == sink) return flow;
	int cursize = G[current].size();
	for (int &i = turn[current]; i < cursize; i++) {
		int node = G[current][i];
		int n;
		if (node == 0) n = current - C;
		else if (node == 1) n = current + C;
		else if (node == 2) n = current - 1;
		else n = current + 1;
		if (edge[current][node] && level[n] == level[current] + 1) {
			int f = dfs(n, min(edge[current][node], flow));
			if (f) {
				edge[current][node] -= f;
				if (node == 0) edge[n][1] += f;
				else if (node == 1) edge[n][0] += f;
				else if (node == 2) edge[n][3] += f;
				else edge[n][2] += f;
				return f;
			}
		}
	}
	return 0;
}

void solve() {
	cin >> R >> C; RC = R * C;
	for (int i = 0; i < RC; i++) G[i].clear();
	memset(edge, 0, sizeof(edge));
	int sr, sc; cin >> sr >> sc; source = sr * C + sc;
	int tr, tc; cin >> tr >> tc; sink = tr * C + tc;
	for (int r = 0; r < R; r++) {
		for (int c = 1; c < C; c++) {
			int w; cin >> w;
			if (w) {
				w = w * 1000 + 1000;
				edge[r * C + c][2] = w;
				edge[r * C + c - 1][3] = w;
				G[r * C + c].push_back(2);
				G[r * C + c - 1].push_back(3);
			}
		}
	}
	for (int r = 1; r < R; r++) {
		for (int c = 0; c < C; c++) {
			int w; cin >> w;
			if (w) {
				w = w * 1000 + 1000;
				edge[r * C + c][0] = w;
				edge[(r - 1) * C + c][1] = w;
				G[r * C + c].push_back(0);
				G[(r - 1) * C + c].push_back(1);
			}
		}
	}
	
	int flow = 0;

	while (bfs()) {
		memset(turn, 0, sizeof(turn));
		int f;
		while (f = dfs(source, INF)) flow += f;
	}

	cout << flow << '\n';
}

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

	int T; cin >> T;
	while (T--) {
		solve();
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 15892 // C++] 사탕 줍는 로봇  (0) 2021.08.12
[BOJ 3013 // C++] 부분 수열의 중앙값  (0) 2021.08.11
[BOJ 3000 // C++] 직각 삼각형  (0) 2021.08.09
[BOJ 1256 // C++] 사전  (0) 2021.08.08
[BOJ 13140 // C++] Hello World!  (1) 2021.08.07

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

 

이번에 볼 문제는 백준 3000번 문제인 직각 삼각형이다.
문제는 아래 링크를 확인하자.

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

 

3000번: 직각 삼각형

첫째 줄에 점의 개수 N(3 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 점의 좌표가 X Y 순서대로 주어진다. (1 ≤ X,Y ≤ 100,000) 겹치는 점은 없다.

www.acmicpc.net

각 주어진 좌표별로, 각 좌표를 "직각인 각을 갖는" 꼭짓점으로 하는 직각삼각형의 개수를 센다고 생각하면 식을 세울 수 있다.

 

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

#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

int X[100001];
int Y[100001];

pair<int, int> points[100000];

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

	int N; cin >> N;
	for (int i = 0; i < N; i++) {
		int x, y; cin >> x >> y;
		points[i] = { x,y };
		X[x]++;
		Y[y]++;
	}

	ll ans = 0;

	for (int i = 0; i < N; i++) {
		ans += ((ll)X[points[i].first] - 1) * ((ll)Y[points[i].second] - 1);
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 3013 // C++] 부분 수열의 중앙값  (0) 2021.08.11
[BOJ 5406 // C++] No Smoking, Please  (0) 2021.08.10
[BOJ 1256 // C++] 사전  (0) 2021.08.08
[BOJ 13140 // C++] Hello World!  (1) 2021.08.07
[BOJ 1939 // C++] 중량제한  (0) 2021.08.06

+ Recent posts