반응형

문제링크:https://www.acmicpc.net/problem/2644

 

2644번: 촌수계산

사람들은 1, 2, 3, …, n (1≤n≤100)의 연속된 번호로 각각 표시된다. 입력 파일의 첫째 줄에는 전체 사람의 수 n이 주어지고, 둘째 줄에는 촌수를 계산해야 하는 서로 다른 두 사람의 번호가 주어진다. 그리고 셋째 줄에는 부모 자식들 간의 관계의 개수 m이 주어진다. 넷째 줄부터는 부모 자식간의 관계를 나타내는 두 번호 x,y가 각 줄에 나온다. 이때 앞에 나오는 번호 x는 뒤에 나오는 정수 y의 부모 번호를 나타낸다. 각 사람의 부모는 최대

www.acmicpc.net

 

처음에 보자마자 생각난건 union-find 알고리즘이였다. 서로 친척인지 확인을 해주기 위한 방법으로 사용하였다.

그이후에는 몇가지 케이스를 대입보면서 촌수계산을 분명하게 하기위해서는 완전탐색을 해야하는 것을 깨닭았고,

dfs와 bfs중에 고민하였다. 아마 dfs로도 풀이가 가능할 것이다. 탐색에 좀 더 적합한 bfs를 선택했다.

 

 

 

1. search_root() 함수를 통해서 서로 친척인지 확인 

2. 출발점x로부터 y까지 도달하는 과정에서 각 값들을 큐에 저장하며 해당 직계도를 탐색

3. bfs함수 호출이 끝난후 cnt[y]값을 출력 ( 전달받아 오면서 값이 +1씩 증가했으므로 촌수와 동일)

 

bfs에서 !visited[arr[i][1]] 의 조건은 최소의 촌수를 선택해야하기 때문입니다. 

 

 

정답코드입니다. 

 

#include <iostream>
using namespace std;
int n = 0, m = 0, x, y,a,b;
int arr[101][2] = { 0 };
int root_x, root_y;
int cnt[101] = { 0 };
bool visited[101] = { 0 };

void bfs() {

	int que[101] = { 0 };
	int started = 0, ended = 0;

	que[ended++] = x;

	while (started != ended) {
		int val = que[started++];
		visited[val] = 1;

		for (int i = 0; i < m; i++) {
			if (arr[i][0] == val && !visited[arr[i][1]]) {
				
				que[ended++] = arr[i][1];
				cnt[arr[i][1]] = cnt[val] + 1;
			}

			if (arr[i][1] == val && !visited[arr[i][0]]) {
				
				que[ended++] = arr[i][0];
				cnt[arr[i][0]] = cnt[val] + 1;
			}

		}


	}

}


void search_root() {

	root_x = x;
	root_y = y;

	while (1) {
		bool t = false, r = false;
		for (int i = 0; i < m; i++) {
			if (arr[i][1] == root_x) {
				t = true;
				root_x = arr[i][0];

			}
			if (arr[i][1] == root_y) {
				r = true;
				root_y = arr[i][0];
			}
		}
		if (t == false && r == false)
			break;
	}
}


int main() {
	cin >> n;
	cin >> x >> y;
	cin >> m;
	for (int i = 0; i < m; i++)
		cin >> arr[i][0]>>arr[i][1];
	
	search_root();
	if (root_x != root_y) {
		cout << -1 << endl;
		return 0;
	}

	bfs();

	cout << cnt[y] << endl;

}

 

움.. 그런데... 생각해보니 searchroot가 필요가 없죠? 어차피 탐색이 안되면 cnt[y]값을 0일 것이기 때문에 그때만 -1로 출력을 해주면 되기 때문입니다.

 

수정답안 입니다.

 

 

#include <iostream>
using namespace std;
int n = 0, m = 0, x, y,a,b;
int arr[101][2] = { 0 };
int root_x, root_y;
int cnt[101] = { 0 };
bool visited[101] = { 0 };

void bfs() {

	int que[101] = { 0 };
	int started = 0, ended = 0;

	que[ended++] = x;

	while (started != ended) {
		int val = que[started++];
		visited[val] = 1;

		for (int i = 0; i < m; i++) {
			if (arr[i][0] == val && !visited[arr[i][1]]) {
				
				que[ended++] = arr[i][1];
				cnt[arr[i][1]] = cnt[val] + 1;
			}

			if (arr[i][1] == val && !visited[arr[i][0]]) {
				
				que[ended++] = arr[i][0];
				cnt[arr[i][0]] = cnt[val] + 1;
			}

		}


	}

}

int main() {
	cin >> n;
	cin >> x >> y;
	cin >> m;
	for (int i = 0; i < m; i++)
		cin >> arr[i][0]>>arr[i][1];
	
	
	
	bfs();
	if (cnt[y]==0) {
		cout << -1 << endl;
		return 0;
	}

	cout << cnt[y] << endl;
	return 0;
}

 

아이디어자체를 생각하는게 어려운 문제였습니다. 구현난이도는 굉장히 낮구요.

반응형
반응형

문제링크: https://www.acmicpc.net/problem/7562

 

7562번: 나이트의 이동

문제 체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수 있을까? 입력 입력의 첫째 줄에는 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 세 줄로 이루어져 있다. 첫째 줄에는 체스판의 한 변의 길이 l(4 ≤ l ≤ 300)이 주어진다. 체스판의 크기는 l × l이다. 체스판의 각 칸은 두 수의 쌍 {0, ...

www.acmicpc.net

 

bfs 문제입니다. 

처음에 문제를 접했을때 dfs로 풀어야지 하고 신나게 작성하다가 깨닭았네요...

dfs에서는 탐색횟수 문제 때문에 visit여부를 판단해야 하는데 그렇게 되면 대다수의 상황에서 탐색이 이뤄지지 않습니다.

 

1)  큐에 시작좌표를 넣어주고

2)  큐의 시작점과 끝점이 같아질때 까지 반복합니다.

3)  나이트가 갈 수 있는 8가지의 경우에 수를 탐색하며 큐에 넣습니다.

4)  탐색중 도착좌표에 도착하면 arr값을 반환하며 종료합니다.

 

우선 arr는 자신이 몇번째에 도착했는지 카운팅하는 배열입니다. 

이때 if (arr[y + dir_y[i]][x + dir_x[i]]) continue; 이 예외처리가 필요합니다.

그 이유는 기존에 탐색했던 곳이라면 더 빠른경로가 저장되어 있을텐데 그값을 덮는 것은 더 느린 방법으로 해당좌표에 도달하는 값을 저장하는 일이기 때문입니다.

 

 

정답코드입니다. 읽어보고 꼭 직접작성해보세요. :) 화이팅

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

int t = 0, l = 0;
int start_y, start_x, defi_y, defi_x, result;
int que[90000][2] = { 0 };
int started = 0, ended = 0;
int arr[301][301] = { 0 };
int dir_y[8] = { -2,-1, 1, 2, 2, 1,-1,-2 };
int dir_x[8] = {  1, 2, 2, 1,-1,-2,-2,-1 };

int bfs() {
	int cnt = 0;

	que[ended][0] = start_y;
	que[ended][1] = start_x;
	ended++;

	while (started != ended) {
		//cout << ended << endl;
		int y = que[started ][0];
		int x = que[started ][1];
		started++;
		if (y == defi_y && x == defi_x) {
			cout << arr[y][x] << endl;
			return 0;
		}
		
		for (int i = 0; i < 8; i++) {
			if (arr[y + dir_y[i]][x + dir_x[i]]) continue;
			if ((y + dir_y[i]) >= 0 && (y + dir_y[i]) < l && (x + dir_x[i]) >= 0 && (x + dir_x[i]) < l) {
				que[ended][0] = y + dir_y[i];
				que[ended][1] = x + dir_x[i];
				ended++;
				arr[y + dir_y[i]][x + dir_x[i]] = arr[y][x] + 1;
			}
		}
	}

}

int main() {
	cin >> t;

	while (t--) {
		started = 0;
		ended = 0;
		cin >> l;

		cin >> start_y >> start_x;
		cin >> defi_y >> defi_x;

		memset(arr, 0, sizeof(arr));
		
		bfs();
	}

}
반응형

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

[백준] 9205-맥주 마시면서 걸어가기(C++)  (0) 2020.03.12
[백준] 5014-스타트링크(C++)  (1) 2020.03.12
[백준] 2589-보물섬(C++)  (0) 2020.03.08
[백준] 2644-촌수계산(C++)  (0) 2020.03.08
[백준] 7569-토마토(C++)  (0) 2020.03.05
반응형

문제링크: https://www.acmicpc.net/problem/11403

 

11403번: 경로 찾기

가중치 없는 방향 그래프 G가 주어졌을 때, 모든 정점 (i, j)에 대해서, i에서 j로 가는 경로가 있는지 없는지 구하는 프로그램을 작성하시오.

www.acmicpc.net

기본적인 dfs, bfs 문제였습니다.

 

숫자범위도 n=100까지이고 dfs를 사용해도 지장이 없을 것 같아 직관적인 dfs 알고리즘을 사용해 구현하였습니다.

 

 

반복문을 통해 arr[i][j]=1일땐 dfs를 호출해 해당줄에서 방문이 가능한 도시를 체크합니다.

방문 이후에는 통합시켜주며 마무리합니다.

 

#include <iostream>
using namespace std;
int n = 0;
int arr[101][101] = { 0 };
bool visited[101];

void dfs(int y, int x) {
	
	for (int i = 1; i <= n; i++) {
		if (arr[x][i] == 1 && !visited[i]) {
			visited[i] = 1;
			dfs(y, i);
		}	
	}
	
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) 
			cin >> arr[i][j];
			
	for (int i = 1; i <= n; i++) {

		for (int j = 1; j <= n; j++)
			visited[j] = 0;

		for (int j = 1; j <= n; j++)
			if (arr[i][j] == 1) {
				visited[j]=1;
				dfs(i, j);
			}

		for (int j = 1; j <= n; j++) {
			if (visited[j] == 1)
				arr[i][j] = 1;
		}
	}
	
	
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cout << arr[i][j] << ' ';
		}
		cout << endl;
	}
}

 

밑에는 dfs, bfs 를 안쓰고 O(n^3)만에 끝내는 컴팩트한 방법입니다.

#include <iostream>
using namespace std;
int main(){
	int n; 
	cin >> n;
	bool map[101][101] = {};
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++) cin >> map[i][j];
	}
	for(int k = 0; k < n; k++){
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				if(map[i][k] && map[k][j]) map[i][j] = true;
			}
		}
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++) cout << map[i][j] << ' ';
		cout << '\n';
	}
}
반응형

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

[백준] 2661-좋은수열(C++)  (0) 2020.03.30
[백준] 15666-N과 M (12)(C++)  (0) 2020.03.25
[백준] 10026-적록색약(C++)  (0) 2020.03.12
[백준] 2668-숫자고르기(C++)  (0) 2020.03.11
[백준] 2583-영역구하기(C++)  (0) 2020.03.11
반응형

이전 포스팅들에서 블럭체인이 무엇인가에 대해서 배웠다.

탈중앙화된 금융을 줄여 ‘디파이(Decentralized Finance, De-Fi)’라 부른다. 블럭체인 기술을 금융권에서 사용되는 것들이 De-Fi가 되는 것이다. 블럭체인 기술이 가장 많이 사용되는 방향이다. 

 

 

 

블록체인 기술이 금융 영역에 들어오면서 나타나고 있는 것이 디파이다. 디파이는 기존 금융기관이 했던 역할을 블록체인을 통해 암호화폐로 대체하려는 시도다. 송금부터 결제, 금융상품 등 기존 금융 산업의 전유물이었던 것들이 블록체인과 암호화폐로 이뤄지는 생태계가 디파이다. 따라서 디파이에는 암호화폐로 행하는 거의 모든 행위가 포함된다. ICO와 IEO, STO, 암호화폐 지갑, 자산의 토큰화 등도 디파이에 해당한다. 

위 그림은 이더리움 defi의 생태계 구조도이다.

 

 

 

디파이는 모든 금융 서비스가 스마트 컨트랙트를 통해 자동으로 이뤄지기 때문에 중개자가 필요 없는 것이 특징이다. 해외에는 이미 디파이를 통한 금융서비스가 한창이다. 덴마크에서 시작한 디파이 전문 업체 메이커다오는 이미 디파이 시장을 선점하고 있다. 암호화폐 대출 서비스를 지원하는 해외의 많은 플랫폼에서는 메이커다오의 스테이블 코인 ‘메이커’와 ‘다이’를 통해 암호화폐 예치 및 대출이 가능하다. 비트코인이나 이더리움 등의 암호화폐로도 대출이 가능하지만 스테이블코인이라는 장점 때문에 메이커다오의 시장 점유율이 가장 높다.

 

 

 

 

핀테크시장의 전쟁과 함께 디파이이도 많은 주목을 받고 있고 핵심기술로써, 함께 성장해 나갈 것으로 예상된다. 

반응형
반응형

문제링크:https://www.acmicpc.net/problem/7569

 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100, 1 ≤ H ≤ 100 이다. 둘째 줄부터는 가장 밑의 상자부터 가장 위의 상자까지에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 하나의 상자에 담긴 토마토의 정보가 주어진다. 각 줄에는 상자 가로줄에 들어있는 토마

www.acmicpc.net

 

BFS알고리즘의 입문용 문제인 토마토 입니다. 기존 토마토와 다른점은 2차원배열을 사용한다는 점입니다.

BFS는 큐를 이용해서 문제를 해결합니다. 

 

 

 

 

입문할때 풀었던 코드라, 난잡하지만 BFS에 대해서 이해하시기는 좋을 것이라고 생각합니다. 

아래는 정답코드입니다.

#include <iostream>
#include<cstring>
#include <queue>
using namespace std;
int arr[102][102][102];
int m = 0, n = 0, cnt = 0, h = 0;
queue<int> x;
queue<int> y;
queue<int> z;

void find(void) {

	for (int k = 1; k <= h; k++)
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {

				if (arr[i][j][k] == 1) { x.push(j), y.push(i), z.push(k); }

			}
		}
}
int search(int sized) {
	if (sized == 0) return 0;
	while (sized--) {
		int x_x = x.front();
		int y_y = y.front();
		int z_z = z.front();
		if (arr[y_y - 1][x_x][z_z] == 0) y.push(y_y - 1), x.push(x_x ),z.push(z_z), arr[y_y - 1][x_x][z_z] =1;
		if (arr[y_y + 1][x_x][z_z] == 0) y.push(y_y + 1), x.push(x_x), z.push(z_z), arr[y_y + 1][x_x][z_z] = 1;
		if (arr[y_y][x_x - 1][z_z] == 0) y.push(y_y), x.push(x_x-1), z.push(z_z), arr[y_y ][x_x-1][z_z] = 1;
		if (arr[y_y][x_x + 1][z_z] == 0) y.push(y_y), x.push(x_x + 1), z.push(z_z), arr[y_y][x_x + 1][z_z] = 1;
		if (arr[y_y][x_x][z_z - 1] == 0) y.push(y_y), x.push(x_x ), z.push(z_z - 1), arr[y_y][x_x][z_z - 1] = 1;
		if (arr[y_y][x_x][z_z + 1] == 0) y.push(y_y), x.push(x_x), z.push(z_z + 1), arr[y_y][x_x][z_z + 1] = 1;
		x.pop(), y.pop(), z.pop();
	}
	return 1;
}
int search2() {
	for (int k = 1; k <= h; k++)
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				{
					if (arr[i][j][k] == 0 && arr[i - 1][j][k] == -1 && arr[i + 1][j][k] == -1 && arr[i][j - 1][k] == -1 && arr[i][j + 1][k] == -1)
						if (arr[i][j][k - 1] == -1 && arr[i][j][k + 1] == -1)
							return 1;

				}
			}
		}
	return 0;
}
int main()
{
	memset(arr, -1, sizeof(int) * 102 * 102 * 102);
	cin >> m >> n >> h;
	for (int k = 1; k <= h; k++) {
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				cin >> arr[i][j][k];
	}


	if (search2() == 1) {
		cout << -1 << '\n';
		return 0;
	}
			
		
	find();

	while (1) {
		int sd = x.size();
		if (search(sd) == 0) break;
		cnt++;
	
		
	}
		
	cout << cnt-1 << '\n';
}
반응형
반응형

문제링크:https://www.acmicpc.net/problem/8980

 

8980번: 택배

입력의 첫 줄은 마을 수 N과 트럭의 용량 C가 빈칸을 사이에 두고 주어진다. N은 2이상 2,000이하 정수이고, C는 1이상 10,000이하 정수이다. 다음 줄에, 보내는 박스 정보의 개수 M이 주어진다. M은 1이상 10,000이하 정수이다. 다음 M개의 각 줄에 박스를 보내는 마을번호, 박스를 받는 마을번호, 보내는 박스 개수(1이상 10,000이하 정수)를 나타내는 양의 정수가 빈칸을 사이에 두고 주어진다. 박스를 받는 마을번호는 보내는 마을번호

www.acmicpc.net

 

그리디 알고리즘 문제였습니다.

우선 첫번째로 조심하셔야 하는 점은 1.도착지 2.출발지 순으로 오름차순 정렬을 해줘야 한다는 것 입니다.

저는 항상 최선의 선택을 한다는 점에 너무 집중을 해서 1.출발지 2.도착지순으로 정렬을 해서 오답을 받았습니다. ㅠㅠ

 

이때 

4 40

3

1 4 40

2 3 40

3 4 40

과같은 입력이 들어오면 오답처리가 됩니다. (정상출력:80 오답:40)

 

 

1) 따라서 1.도착지 2.출발지 순으로 오름차순 정렬을 해야합니다.

 

2) 정렬 후 m번 반복하며 해당박스들을 받을 수 있는지, 얼마나 들어갈 수 있는지 확인합니다.

( 그러기 위해서는 해당위치에 박스를 얼마나 적재했는지 표시하는 int형 배열이 필요합니다.) -> capacity

 

3) 1. 시작도시부터 도착도시까지 가장 많이 적재된 박스양을 구합니다.

   2. 구한 값을 통해 해당도시에서 받을 수 있는 박스량 만큼 결과 값에 더해줍니다.

   3. 시작도시부터 도착도시까지 적재한 박스양을 capacity에 더해줍니다.

 

3)번과 같은 과정을 m번 반복하며 결과값을 결정하는 것입니다.

 

 

정답코드입니다. 꼭 직접 작성해보세요.

 

 

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

struct info {
	int sender;
	int reciever;
	int cnt;

	
};

info arr[10000];
int capacity[10001] = { 0 };
int n = 0, c = 0, m = 0;
int result = 0;

bool cmp(info a, info b) {
	if (a.reciever < b.reciever)return true;
	else if (a.reciever == b.reciever)
		if (a.sender < b.sender)
			return true;
		
	return false;
}

int main() {
	
	cin >> n >> c;
	cin >> m;

	for (int i = 0; i < m; i++)
		cin >> arr[i].sender >> arr[i].reciever >> arr[i].cnt;

	sort(arr, arr + m,cmp); //오름차순 정렬 1.도착지 2.출발지 

	for (int i = 0; i < m; i++) { 
		
		int maxcnt = 0;
		for (int j = arr[i].sender; j < arr[i].reciever; j++)  //보내는곳부터 받는곳까지
			maxcnt = max(capacity[j], maxcnt); //capacity의 최대값을 저장합니다. 박스를 얼마나 넣을 수 있는 확인하기 위해

		int val = min(arr[i].cnt, c - maxcnt);
		result += val;
		
		for (int j = arr[i].sender; j < arr[i].reciever; j++) {
			capacity[j] += val; // 이동되면서 해당 공간만큼 할당해주어야 박스가 못 실리겠죠
		}

	}

	
	cout << result << endl;

}
반응형

'알고리즘 > 그리디 알고리즘' 카테고리의 다른 글

[백준] 1092-배(C++)  (0) 2020.05.05
[백준] 10825-국영수(C++)  (0) 2020.03.13
[백준] 1969-DNA(C++)  (0) 2020.03.03
[백준] 2437-저울(C++)  (0) 2020.03.03
[백준] 1783-병든 나이트(C++)  (0) 2020.03.02
반응형

JavaScript 언어는 주로 어디에 사용될까요??

웹프로그래밍에서 동적으로 움직이는 화면들에 사용됩니다. 그리고 새로고침이 되지 않았는데 동적으로 움직이는 텍스트들에도 사용됩니다.  JavaScript도 하나의 프로그래밍 언어이기에 프론트단에서 그러한 움직을 만들수 있는 것입니다. 

 

 

JavaScript를 크롬(Chrome)같은 브라우저에서만 쓰는 것이 아닌 브라우저 밖. 즉, 내 컴퓨터에서 다양한 용도로 확장하기 위해 만들어진 것이 바로 Node.js입니다. Node.js를 이용하면 Python과 같이 내 컴퓨터에서 File System를 이용할 수 있고, 서버를 만들 수도 있고 크롤링도 할 수 있습니다. JavaScript도 Python과 같은 프로그래밍 언어이기 때문입니다.

 

 

 

Node.js를 이용하여 Express같은 라이브러리를 이용해서 서버를 만들곤하지만, Node.js 자체는 웹서버가 아닙니다.  Node.js는 자바스크립트 런타임(JavaScript Runtime)으로 Node.js는 웹 서버를 만들 수 있는 하나의 방법에 불과합니다.

 

 

 

Node.js의 특징

1.비동기 I/O 처리: Node.js 라이브러리의 모든 API는 비동기식(async)입니다, 멈추지 않는다는거죠 (Non-blocking). Node.js 기반 서버는 API가 실행되었을때, 데이터를 반환할때까지 기다리지 않고 다음 API 를 실행합니다. 그리고 이전에 실행했던 API가 결과값을 반환할 시, Node.js의 이벤트 알림 메커니즘을 통해 결과값을 받아옵니다.

 

 

2. 빠른 속도: 구글 크롬(Google Chrome)의 V8 자바스크립트 엔진(JavaScript Engine)을 사용하여 빠른 코드 실행을 제공합니다.

 

 

3. 단일 쓰레드와 뛰어난 확장성: Node.js는 이벤트 루프와 함께 단일 쓰레드 모델을 사용합니다. 이벤트 메커니즘은 서버가 멈추지않고 반응하도록 해주어 서버의 확장성을 키워줍니다. 반면, 아파치(Apache)같은 일반적인 웹서버는 요청을 처리하기 위하여 제한된 쓰레드를 생성합니다. Node.js 는 쓰레드를 한개만 사용하고 아파치(Apache)같은 웹서버보다 훨씬 많은 요청을 처리할 수 있습니다.

 

Node.js를 쓰기 적합한 곳

다음과 같은 경우에 Node.js를 사용할 경우 좋은 효율성을 발휘할 수 있습니다.

  • 알림이나 실시간 대화같이 같이 데이터의 실시간 처리가 필요한 애플리케이션
  • 사용자의 입력과 출력이 잦은 애플리케이션
  • 데이터 스트리밍 애플리케이션
  • JSON API기반의 애플리케이션
  • 단일 페이지 기반의 애플리케이션

웹외에도, 장치를 조작하는데도 많이 사용됩니다. 

다음부터의 제 포스팅에서는 라즈베리파이에서의 node.js를 활용한 정보전달 및 장치제어에 초점을 두고 포스팅 하겠습니다.

반응형
반응형

문제 링크: https://www.acmicpc.net/problem/1969

 

1969번: DNA

문제 DNA란 어떤 유전물질을 구성하는 분자이다. 이 DNA는 서로 다른 4가지의 뉴클레오티드로 이루어져 있다(Adenine, Thymine, Guanine, Cytosine). 우리는 어떤 DNA의 물질을 표현할 때, 이 DNA를 이루는 뉴클레오티드의 첫글자를 따서 표현한다. 만약에 Thymine-Adenine-Adenine-Cytosine-Thymine-Guanine-Cytosine-Cytosine-Guanine-Adenine-Thymine로 이루어진

www.acmicpc.net

 

문제만 이해하면 그리디적인 개념으로 쉽게 풀 수 있는 문제였습니다.

모든 문자열에서 인덱스값들중 가장 큰 값만을 결과문자열로 저장하고 그값과 달랐던 값을 카운트해서 결과값을 도출하면 됩니다. 

 

 

문제 조건에서 사전순으로 가장 앞서는 것을 출력한다. 라는 규칙을 주의해서 풀어 주시면 됩니다. 

아스킷 코드값을 참조하며 arr[word[j][i] - 'A']++; 의 의미가 무엇인지, 그리고 arr[26]인지 생각해보세요.

 

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

int n, m;
string word[1000];
int result_sum = 0;
string result;
int main() {
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		cin >> word[i];
	


	for (int i = 0; i < m; i++) {
		int arr[26] = { 0 }, maxed = 0, max_index = 0;
		for (int j = 0; j < n; j++) {
			arr[word[j][i] - 'A']++; 
		}
		for (int j = 0; j < 26; j++) {
			if (maxed < arr[j]) maxed = arr[j],max_index = j;
		}
		result_sum += n - maxed;
		result += max_index + 'A';
	}

	cout << result << endl;
	cout << result_sum << endl;

}

화이팅:)

반응형

'알고리즘 > 그리디 알고리즘' 카테고리의 다른 글

[백준] 1092-배(C++)  (0) 2020.05.05
[백준] 10825-국영수(C++)  (0) 2020.03.13
[백준] 8980-택배(C++)  (0) 2020.03.05
[백준] 2437-저울(C++)  (0) 2020.03.03
[백준] 1783-병든 나이트(C++)  (0) 2020.03.02

+ Recent posts