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

 

3055번: 탈출

사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제

www.acmicpc.net

 

코드 설명

큐를 2개를 이용하였다. start큐는 이동하는 경로, water 큐는 물의 경로이다.

일반 BFS while()문 내에 각각의 큐를 넣어 반복하였다.

 

전체 while()문 내에

 

1. 먼저 물 4방향씩 이동 ( 이동 후 물(*) 찍어주기)

2. 이후 고슴도치 4방향 탐색 이동 ( visited배열 사용했습니다)

3. 하루 증가

과 같이 계속해서 반복해주었습니다. 

 

 

배운점!!

매번 BFS를 이용하여 끝까지 탐색하는것만 생각했는데 큐의 사이즈를 이용 +  이중while문  활용 하여 한칸씩 이동후 검사하는 방법!

 

코드 

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
char map[51][51];
int R, C;

bool flag;
bool visited[51][51];
beaver target;
int dy[] = { -1,1,0,0 };
int dx[] = { 0,0,1,-1 };
int cnt;
queue<pair<int, int>> start;
queue<pair<int, int>> water;
void BFS() {
	

	while (!start.empty()) { // 전체 while
		cnt++; // 날짜하루증가
		int w_size = water.size();
		while (w_size--) { //물먼저이동

			int y = water.front().first;
			int x = water.front().second;
			water.pop();

			for (int i = 0; i < 4; i++) {
				int ny = y + dy[i];
				int nx = x + dx[i];
				if (ny < 0 || nx < 0 || ny >= R || nx >= C) continue;
				if (map[ny][nx] == '*' || map[ny][nx] == 'X'||map[ny][nx]=='D') continue;
				map[ny][nx] = '*'; //맵에 물 표기 
				water.push({ ny,nx });

			}

		}

		//S이동
		int s_size = start.size();
		visited[start.front().first][start.front().second] = true;
		while (s_size--) {
			int y = start.front().first;
			int x = start.front().second;
			if (map[y][x] == 'D') { //도착
				cout << cnt - 1;
				flag = true;
			}
			start.pop();

			for (int i = 0; i < 4; i++) {
				int ny = y + dy[i];
				int nx = x + dx[i];
				if (ny < 0 || nx < 0 || ny >= R || nx >= C) continue;
				if (map[ny][nx] == '*' ||map[ny][nx] == 'X') continue;
				if (!visited[ny][nx]) {
					visited[ny][nx] = true;
					start.push({ ny,nx });


				}
			}



		}




	}
	if (flag == false) cout << "KAKTUS"; //비버굴 만나지 못한경우 
	



}

int main() {

	cin >> R >> C;
	for (int y = 0; y < R; y++) {
		for (int x = 0; x < C; x++) {
			cin >> map[y][x];

			if (map[y][x] == 'S') {
				start.push({ y,x });

			}
			else if (map[y][x] == '*') {
				water.push({ y,x });
			}



		}
	}


	BFS();



	return 0;
}

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

 

2468번: 안전 영역

재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는

www.acmicpc.net

 

코드 설명

강수량 높이를 0부터 하지 않아서 계속해서 반례를 찾아보느라 시간이 오래 걸렸다.

그 외 while안에 이중 for문을 담아서 계속해서 visited배열을 초기화시켜주면서 안전영역이 가장 많을 때를 저장했다.

 

N^3이지만 100^3이라 복잡도면에서 괜찮을 것이라 판단했다.

 

(반례)

3

1 1 1

1 1 1

1 1 1

을 했을때 답:1 이 나와야 한다.

 

코드

//안전한영역의 개수가 최대인경우 찾기
#include<iostream>
#include<queue>
#include<string>
#include<cstring>
using namespace std;
int dy[] = { -1,1,0,0 };
int dx[] = { 0,0,1,-1 };
int map[101][101];

bool visited[101][101];
int N;
void run(int h,int y,int x) {
	queue<pair<int, int>> q;
	visited[y][x] = true;
	q.push({ y,x });

	while (!q.empty()) {
		int y = q.front().first;
		int x = q.front().second;
		q.pop();

		for (int i = 0; i < 4; i++) {
			int ny = y + dy[i];
			int nx = x + dx[i];
			if (ny < 0 || nx < 0 || nx >= N || ny >= N) continue;
			if (!visited[ny][nx] && map[ny][nx] > h) {
				q.push({ ny,nx });
				visited[ny][nx] = true;


			}


		}



	}

}
int main() {
	cin >> N;
	int max = 0;
	for (int y = 0; y < N; y++) {
		for (int x = 0; x < N; x++) {
			cin >> map[y][x];
			if (map[y][x] > max) max = map[y][x];
		}
	}
	//////////

	////
	int aanswer = 0;
	int start = 0;
	while (start <= max) {
		int answer = 0;
		for (int y = 0; y < N; y++) {
			for (int x = 0; x < N; x++) {
				if (!visited[y][x] && map[y][x]>start) {
					run(start,y, x);
					answer++;
				}

			}
		}
		if (aanswer < answer) aanswer = answer;
		start++;
		memset(visited, false,sizeof(visited));
	}
	cout << aanswer;



	return 0;
}

1. 컨테이너란? 

운영체제에서 실행되는 프로세스를 격리하여 별도의 실행 환경을 제공해주며, 해당 프로세스는 운영체제상에서 실행되는 유일한 프로세스인 것처럼 작동한다. 즉, 운영체제에서 실행되는 여러 프로세스는 컨테이너라는 개념으로 격리되어 별도의 운영환경을 제공하는 기술이다.

 

컨테이너 환경을 제공하는 기술 

chroot

Docker

LCX

Solaris Containers(Zones)

FreeBSD Jail

WPARS(AIX)

rkt

 

2. 컨테이너 아키텍처

리눅스 시스템에서 컨테이너를 이용하여 격리 구조를 만드는 기법은, 격리를 담당하는 Linux Namespace와 리소스를 제어하는 Control Group(cgroup)을 사용하여 격리된 컨테이너 환경을 제공한다.

 

네임스페이스 종류

마운트 포인트

프로세스

네트워크 - IPC

UTS

사용자

 

제어 그룹은 프로세스 또는 컨테이너가 사용할 수 있는 리소스의 양을 제한 할 수 있다. (CPU, 메모리, 네트워크 대역폭, 디스크 입출력)

 

3. 도커 컨테이너

컨테이너 기술은 오래전부터 존재해왔던 기술이지만 Docker Inc가 만든 도커 플랫폼의 등장으로 컨테이너 플랫폼에 대해 널리 알려지고 쉽게 사용할 수 있게 되었다. 도커는 네임스페이스와 제어 그룹 기술을 사용하여 애플리케이션을 패키징, 배포 실행하는 플랫폼이다.

 

주요 개념 

이미지 : 실행할 애플리케이션과 라이브러리 및 환경을 하나의 패키지로 묶은 것

레지스트리 : 이미지를 저장하고 공유할 수 있는 스토리지

도커 허브 등과 같은 공용 레지스트리와 개인 및 특정 시스템만 사용할 수있는 사설 레지스트리를 직접 구축할 수 있다.

컨테이너 : 이미지를 실행할 컨테이너 

 

도커는 컨테이너를 주류 기술로 만든 최초의 컨테이너 플랫폼으로 , 쿠버네티스에서 기본적으로 애플리케이션을 구동하기 위한 구성요소 중 하나이다.

현재 쿠버네티스는 도커 이외에도 컨테이너 형식 및 컨테이너 런타임에 대한 개방된 표준을 만드는 OCI가 생겨, OCI표준의 컨테이너 대부분을 지원한다. (대표적으로 rkt)

 

컨테이너 vs 가상머신 

가상 머신은 애플리케이션을 동작시키기 위해서 애플리케이션이 사용하는 리소스만 사용하는 것뿐만 아니라 운영체제가 동작하기 위한 리소스가 추가로 필요하다. 그러나 컨테이너는 애플리케이션이 동작하기 위한 리소스만 사용하기 때문에 훨씬 더 빠르고 가볍게 동작한다.

 

도커와 가상머신 비교

 

쿠버네티스란?

쿠버네티스는 '조타수' '파일럿'을 뜻하는 그리스어에서 유래하였으며 K8s라고 부르는데 이는 국제화를 110n으로 표기하는 것과 같이 'ubernete' 글자 개수로 대체한 약어이다. 

 

구글은 전 세계 적으로 수십만 대의 서버를 운영하고 있으며, 소프트웨어와 인프라를 전 세계에 확장될 수 있는 훨씬 진보된 방법을 찾았고 Borg라는 내부 시스템을 개발하여 개발자와 관리자가 수천 개의 애플리케이션과 서비스를 관리하는데 도움을 주었다. 

 

이후 구글의 Borg 시스템은 쿠버네티스란 이름으로 오픈소스를 공개하고, 이를 Linux 재단 산하의 CNCF 재단에 기증하였다. CNCF는 컨테이너 기술 및 주위 기술에 대한 프로젝트를 담당한다.

 

쿠버네티스가 제공하는 기본 기능 요약

컨테이너 플랫폼

마이크로 서비스 플랫폼

이식성 있는 클라우드 플랫폼 

 

즉, 쿠버네티스는 컨테이너 기반의 분산 클러스터 환경을 제공하며 워크로드를 위해 컴퓨팅, 네트워킹 및 스토리지 인프라를 오케스트레이션 한다.

1. 모놀리식 아키텍처

모놀리식 아키텍처는 오늘날에도 널리 사용되고 있는 아키텍처다. 대부분 단일 프로세스에서 실행되거나 몇몇 시스템에서 몇 개의 프로세스로 실행되는 거대한 모놀리식 애플리케이션이었다.

 

모놀리식 아키텍처와 마이크로서비스 아키텍처 비교

장점

1. 간단한 개발

2. 간편한 배포

3. 단순한 확장성

 

모놀리식 아키텍처에서는 애플리케이션을 매번 릴리스 할 때 마다 개발자가 전체 애플리케이션을, Java의 경우 WAR파일을 패키징 하거나, Ruby, Node.js의 경우 단일 디렉터리 계층으로 묶어서 배포해야 했다.

 

단점 

1. 코드 품질이 낮아짐

2. 애플리케이션의 시작이 오래걸림

3. 확장이 어려움

4. 다양한 기술 적용의 어려움

 

모놀리식 애플리케이션은 모든 것이 서로 강하게 결합하여 구성되어 단일 OS의 단일 프로세스로 실행되기 때문에 모든 것을 하나의 애플리케이션으로 개발 배치 관리되어야 한다. 즉, 조그마한 추가 및 변경에서 전체를 재배포해야 한다.

 

2. 마이크로 서비스 아키텍처

모놀리식 아키텍처가 크기가 커짐에 따라 발생하는 문제점을 극복하기 위해 기능적으로 세분화되고 독립적으로 구성

세분화되고, 독립적으로 작동하는 마이크로 서비스 기반의 애플리케이션은 API를 통해 서로 다른 마이크로 서비스와 통신하게 된다. 여러 마이크로 서비스 사이에는 일반적으로 동기방식인 HTTP/RESTful API 또는 비동기 방식인 AMQP프로토콜을 이용하여 통신한다. 

 

장점 

1. 크고 복잡한 애플리케이션을 지속적으로 배포 - 유지보수성, 테스트 용이성, 배포 효율성, 독립 개발, 배포 확장 가능

2. 개발에 대한 생산성 증가 배포 속도 향상

3. 향상된 장애 격리

4. 다양한 기술 적용 가능

 

단점 

1. 분산 설계 시스템에 따른 복잡성 - 서비스 간 통신 메커니즘을 따로 구현해야 함

2. 배포 및 관리 운영상의 복잡성

3. 증가된 리소스 소비 

 

 

3. DevOps

예전에는 개발팀에서 애플리케이션을 개발해 QA에 넘겨주면 테스트 후, 다시 운영팀에게 넘겨주면 애플리케이션을 배포, 관리 및 실행하는 흐름을 가진다. 그러나 최근에는 테스트뿐만 아니라 배포 이상의 작업에 개발자가 관여하고, 애플리케이션의 전체 라이프 사이클을 함께 관리하는 것이 효율적이라는 것을 알게 되었다. 

즉, 이런 소프트웨어 개발, 품질, 운영 팀의 소통 협업 및 통합을 강조하는 개발환경 및 문화를 DevOps라고 한다.

 

DevOps

 

+ Recent posts