문제출처 : https://www.acmicpc.net/problem/14503


1. 문제요약

- 로봇의 행동을 시뮬레이션


2. 접근방법

- 시뮬레이션.... 그냥 있는 그대로 구현


3. 시간복잡도

- O(N^2)


4. 회고

- 종이로 적자... ㅋㅋ

  아이 헷갈려



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14888 연산자 끼워넣기  (0) 2018.02.12
BOJ 14889 스타트와 링크  (0) 2018.02.12
BOJ 2146 다리 만들기  (0) 2018.02.11
BOJ 2178 미로 탐색  (0) 2018.02.11
BOJ 7576 토마토  (0) 2018.02.08

문제출처 : https://www.acmicpc.net/problem/14888


1. 문제요약

- N개의 수로 이루어진 수열 A1, A2, ... , An이 주어진다.

- 수 사이에 끼워 넣을 연산자가 N-1개 주어진다.

- 수의 순서는 고정되어 있고 숫자 사이에 연산자를 넣어서 만들 수 있는 최대값과 최솟값을 출력

- 수식은 +, -, *, / 순이다.

- 2 <= N <= 11


2. 접근방법

- 조합!

- 10! / (덧셈 연산자 갯수)! * (뺄셈 연산자 갯수)! * (곱셈 연산자 갯수)! * (나눗셈 연산자 갯수)!


3. 시간복잡도

- 10! / (덧셈 연산자 갯수)! * (뺄셈 연산자 갯수)! * (곱셈 연산자 갯수)! * (나눗셈 연산자 갯수)!


4. 회고

- 문제에서 음수 / 양수 인 경우 음수를 양수로 바꾸고 나눗셈 연산을 한 뒤에 다시 음수를 붙이라고 해서 

  진짜 그렇게 했는데.. 굳이 그렇게 안해도 그냥 그런식으로 연산이 되는거였네...


- 종만북에 조합관련된 비슷한 문제가 있었던거 같은데... 찾아봐야지


- 처음에 long long 로 max값을 -2e31 / min값을 2e31-1 로 잡았는데 왜 값이 제대로 안들어가지??

- 아.. 음... 엄청 멍청했군.... 2e31 은 2뒤에 0이 31개 있다는 뜻인데 왜 2^31으로 생각했지 ㅋㅋ



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14503 로봇 청소기  (0) 2018.02.12
BOJ 14889 스타트와 링크  (0) 2018.02.12
BOJ 2146 다리 만들기  (0) 2018.02.11
BOJ 2178 미로 탐색  (0) 2018.02.11
BOJ 7576 토마토  (0) 2018.02.08

문제출처 : https://www.acmicpc.net/problem/14889


1. 문제요약

- 총 N명의 사람을 N/2 명씩 팀을 나눔

- 사람 번호를 1, 2, 3, 4라 했을때, 팀 1은 1, 2 / 팀 2는 3, 4

- 팀 능력치는 s[1][2] + s[2][1] 

                  s[3][4] + s[4][2] 이다.(s[1][2], s[2][1]은 서로 다를 수 있다.)

- 팀 능력치 차이가 최소값은?


- 4 <= N <= 20 (N은 짝수)


2. 접근방법

- 한명의 사람이 스타트팀인지 링크 팀인지 구분

- 2^N


3. 시간복잡도

- 2^N


4. 회고

- 난 팀 능력치 계산을 팀을 만들 때 마다 하게 했는데...(사실 재귀를 거치면서 합산하면 된다고 생각은 했지만, 구현을 못했음)

- 그냥 for문으로 선택된 팀원이 i 이미 팀은 팀원을 1, 2 라 하면 sum += s[i][j] + s[j][i]; 하면 되는데...


- 스타트팀 : 1, 2 / 링크팀 : 3, 4 인 경우와

  스타트팀 : 3, 4 / 링크팀 : 1, 2 인 경우는 팀 능력치 차이가 같다.


- 난 이걸 해결 못해서 그냥 모든 경우(2^N)으로 해결했다.


- 해결하는 가장 쉬운 방법은 그냥 1을 한팀에 고정시키면 된다.


- next_permutation으로 4명이면 0 0 1 1을 순열로 만들어서 0 인경우 A팀 1 인경우 B팀으로 구분시키는 방법도 있음

- 사람을 순열돌리는 것보다 시간이 빠르며 최악 20! / 10! * 10! = 190,000



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14503 로봇 청소기  (0) 2018.02.12
BOJ 14888 연산자 끼워넣기  (0) 2018.02.12
BOJ 2146 다리 만들기  (0) 2018.02.11
BOJ 2178 미로 탐색  (0) 2018.02.11
BOJ 7576 토마토  (0) 2018.02.08

문제출처 : https://www.acmicpc.net/problem/2146


1. 문제요약

- 상하좌우로 연결된 섬이 여러개 있음

- 두 섬을 연결하는 최소 다리 길이는?

- 다리의 연결도 상하좌우

- 1 <= n <= 100

- 0은 바다 1은 육지


2. 접근방법

- dfs로 섬마다 번호를 붙임

- bfs로 섬을 한칸씩 확장해나가면서 다른섬을 만나면 다리길이를 비교하여 최소인 경우를 저장


3. 시간복잡도

- O(2n^2)


4. 회고

- queue를 쓰면서 생각지도 못한 경우가 발생함.......

- queue에 들어간 순서에 따라서 답이 달라질 수 있음

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

int n, map[101][101], dist[101][101];
int dr[4] = { -1, 0, 1, 0 };
int dc[4] = { 0, -1, 0, 1 };
queue<pair<int, int> > q;

void dfs(int r, int c, int cnt){
	dist[r][c] = 1;
	map[r][c] = cnt;
	q.push(make_pair(r, c));

	for (int k = 0; k < 4; k++){
		int nr = r + dr[k];
		int nc = c + dc[k];

		if (0 <= nr && nr < n && 0 <= nc && nc < n && dist[nr][nc] == 0 && map[nr][nc] == 1){
			dfs(nr, nc, cnt);
		}
	}
}

int main(void){
	cin >> n;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cin >> map[i][j];

	int cnt = 1;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (dist[i][j] == 0 && map[i][j] == 1)
				dfs(i, j, cnt++);

	bool isans = false;
	while (!q.empty() && !isans){
		int r = q.front().first;
		int c = q.front().second;
		q.pop();

		for (int k = 0; k < 4; k++){
			int nr = r + dr[k];
			int nc = c + dc[k];

			if (0 <= nr && nr < n && 0 <= nc && nc < n){
				if (map[nr][nc] == 0){
					q.push(make_pair(nr, nc));
					map[nr][nc] = map[r][c];
					dist[nr][nc] = dist[r][c] + 1;
				}
                                // 가장 먼저 다른 섬을 발견하면 무조건 최소 다리 길이를 만족 할줄 알았는데 queue에 들어간 순서에 따라 답이 달라 질 수 있음. 반례는 아래 참조
				else if (map[nr][nc] != map[r][c]){
					cout << dist[r][c] + dist[nr][nc] - 2 << "\n";
					isans = true;
					break;
				}
			}
		}
	}

	return 0;
}

- 반례(답 2)

5

10001

00000

00000

00000

11001

인 경우 첫번째 행 좌우섬이 큐에 먼저 들어가기 때문에 아래 다리 2가 아닌 3이 출력됨



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14888 연산자 끼워넣기  (0) 2018.02.12
BOJ 14889 스타트와 링크  (0) 2018.02.12
BOJ 2178 미로 탐색  (0) 2018.02.11
BOJ 7576 토마토  (0) 2018.02.08
BOJ 4963 섬의 개수  (0) 2018.02.08

문제출처 : https://www.acmicpc.net/problem/2178


1. 문제요약

- n * m 크기의 맵이 주어짐

- 1은 갈 수 있는 곳, 0은 갈 수 없는 곳

- (1, 1) 에서 출발해서 (n, m) 까지 지나는 최소 칸수는?

- (1, 1), (n, m) 도 칸 횟수에 포함

- 2 <= n, m <= 100


2. 접근방법

- 맵 최소 이동횟수 = bfs


3. 시간복잡도

- O(n*m)


4. 회고



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14889 스타트와 링크  (0) 2018.02.12
BOJ 2146 다리 만들기  (0) 2018.02.11
BOJ 7576 토마토  (0) 2018.02.08
BOJ 4963 섬의 개수  (0) 2018.02.08
BOJ 14890 경사로  (0) 2018.02.07

문제출처 : https://www.acmicpc.net/problem/7576


1. 문제요약

- 상자에 익은토마토(1), 안익은 토마토(0), 빈칸(-1) 이 있음

- 하루가 지나면 익은 토마토의 상하좌우에 있는 안익은 토마토는 익게됨

- 상자에 있는 토마토가 전부 익을 때 까지 걸리는 일 수는?

- 토마토가 전부 익지 않으면 -1

  익으면 익을때 까지 걸린 일 수를 출력


2. 접근방법

- bfs

- 익은 토마토를 큐에 넣고

  인접(상하좌우) 에 있는 익지 않은 토마토를 다시 인큐

  큐가 빌때 까지 bfs


3. 시간복잡도

- O(n)


4. 회고

- 예전에 섬이 확장할때 마주치는 최소 일수 였나 그 문제랑 비슷하군

- tie를 써서 (row, col, day) 를 저장한 후에 day를 출력해도 되지만

  난 make_pair만 쓰므로 size를 넣어서 day를 계산하게 만듬



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 2146 다리 만들기  (0) 2018.02.11
BOJ 2178 미로 탐색  (0) 2018.02.11
BOJ 4963 섬의 개수  (0) 2018.02.08
BOJ 14890 경사로  (0) 2018.02.07
BOJ 9466 텀 프로젝트  (0) 2018.02.06

문제출처 : https://www.acmicpc.net/problem/4963


1. 문제요약

- 상하좌우 및 4방향 대각선으로 연결된 섬의 개수


2. 접근방법

- dfs, bfs


3. 시간복잡도

- O(n)


4. 회고



소스코드



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 2178 미로 탐색  (0) 2018.02.11
BOJ 7576 토마토  (0) 2018.02.08
BOJ 14890 경사로  (0) 2018.02.07
BOJ 9466 텀 프로젝트  (0) 2018.02.06
BOJ 14891 톱니바퀴  (0) 2018.02.05

문제출처 : https://www.acmicpc.net/problem/14890


1. 문제요약


2. 접근방법


3. 시간복잡도


4. 회고



소스코드 : 내방식


소스코드 : 내가 부족했던 1을 보완한 방식


소스코드 : 생각지도 못한 방식.. 부럽



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 7576 토마토  (0) 2018.02.08
BOJ 4963 섬의 개수  (0) 2018.02.08
BOJ 9466 텀 프로젝트  (0) 2018.02.06
BOJ 14891 톱니바퀴  (0) 2018.02.05
BOJ 2331 반복수열  (0) 2018.01.30

문제출처 : https://www.acmicpc.net/problem/9466


1. 문제요약

- 학생들이 팀을 이룸

- 1 2 3 4 5 6 7

  3 1 3 7 3 4 6


- 2 -> 1 -> 3(3) <- 5

  4 -> 7 -> 6 -> 4


- 3은 혼자서 팀을 이루고 4, 7, 6은 세명이서 팀을 이룸


- 팀에 속하지 않은 학생은 1, 2, 5 로 3명


- 팀에 속하지 않은 학생수는?


2. 접근방법

- 방법1. 위상정렬

  한 정점에서 나가는 간선은 무조건 1개

  한 정점에 들어오는 간선은 여러개

  

  들어오는 간선의 수를 헤아린 뒤에 한 정점을 방문시 다음 정점으로 들어가는 간선을 하나씩 없앰

  사이클을 형성할려면 무조건 들어오는 간선이 하나는 존재 하므로

  모든 정점을 방문하면서 들어가는 간선이 없는 정점을 방문하면 팀이 없는 사람만 골라 낼 수 있음


사이클을 형성하지 않는 노드만 방문하여 갯수를 헤아림

노드를 방문하는 조건은 해당 노드로 들어오는 간선이 없으면 사이클을 형성하지 않는다는 의미이므로 간선이 없을 때 방문

for문으로 노드 1부터 노드 n까지 방문


아.. 음 그림이 좀 잘못됬는데 노드 5에서 노드 3으로 들어가는 화살표 방향이 되어야함.


<fig 1>

초기 해당 노드로 들어오는 간선의 수 초기화

노드 1은 들어오는 간선의 수가 1 이므로 방문하지 않음


<fig 2>

노드 2는 들어오는 간선의 수가 없으므로 첫번째로 방문하게 됨


<fig 3>

노드 2를 방문하면서 노드 1로 이어지는 간선을 없애면 노드 1은 방문 가능한 상태가 되어 방문 하게 됨

노드 1을 방문하면서 노드 3으로 들어가는 간선의 수를 하나 없애도 노드 3은 들어오는 간선의 수가 2이므로 방문하지 않음


<fig 4>

노드 4, 노드 7, 노드 6은 들어오는 간선의 수가 1이므로 방문하지 않음


<fig 5>

노드 5는 들어오는 간선의 수가 0이므로 방문

노드 5를 방문하면서 노드 3으로 들어가는 간선의 수를 하나 없애도 노드 3은 간선의 수가 1 이므로 방문하지 않음

실제로 코드는 노드 4를 확인한 다음 노드 5를 확인함(for문 이므로)



- 방법2. stack

  현재까지 방문한 정점을 stack에 쌓은다음 방문했던 정점을 방문했을 때 스택의 어는 부분에 있는지 확인하여 사이클이 아닌 노드의 갯수를 합침

  check[n]은 방문을 나타내며 0은 방문 하지 않음

                                      1은 방문했지만 아직 팀은 아님

                                      2는 팀에 속함

  check[n]이 1인경우 사이클을 이루는 경우와 이루지 않는 경우로 나눌 수 있는데

  stack을 돌려보고 해당 정점이 스택에 없으면 사이클이 없는 것이므로 현재까지 방문했던 노드갯수를 합침


<fig 5>

노드 1을 방문하고 stack에는 1, check[1] = 1


<fig 6>

노드 3을 방문하고 stack에는 3, check[3] = 1


<fig 7>

노드 3은 다시 노드 3을 방문 즉, check[3] = 1 stack을 돌면서 노드 3이 있는지 확인 후 check[3] = 2


<fig 8>

노드 2를 방문 stack에는 2, check[2] = 1

노드 1이 check[1] = 1인 상태이지만 스택에 없기 때문에 현재까지 방문했던 노드 2를 팀을 이루지 않는 인원에 합산


<fig 9>

노드 4, 7, 6을 순서대로 방문 stack 4, 7, 8, check[4] = check[7] = check[6] = 1


<fig 10>

노드 6의 다음 노드는 노드 4 노드 4는 check[4] = 1이므로 노드 4가 스택에 있는지 확인 후 해당 노드 4 부터 노트 6까지 check[n] = 2로 변경

stack에 8이 아니라 6


<fig 11>

노드 5를 방문 stack 5, check[5] = 1

노드 5의 다음 노드는 노드 3 노드 3은 check[3] = 2이므로 현재까지 방문했던 노드 5를 팀에 속하지 않는 인원에 합산



- 방법3. 1 : 1대응 그래프 특성

  방문하는 노드에 방문 순서를 매김

  한 컴포넌트에서 처음 방문한 노드의 숫자가 한번 방문했던 노드를 다시 방문한 노드의 숫자 보다 작거나 같으면 사이클을 형성하고 있음

  팀을 이루고 있는 전체 인원을 합산하여 전체 학생 수에서 팀 인원을 제외


  check[n]을 노드 n의 방문 순서,

  student[n]을 친구간 연결이라 한다면

  

  if(check[student[now] >= check[start]) team += cnt - check[student[now]] + 1

  ans = n - team


<fig 12>

최초에 모든 노드는 방문한 적이 없으므로 check[n] = 0

cnt = 1

노드 1을 최초 방문 이므로 check[1] = 1


<fig 13>

cnt = 2

노드 3은 노드 1 다음 방문이므로 2번째 check[2] = 2

check[노드 3] = 2

check[1] = 1 이므로

team += 2 - 2 + 1 = 1


<fig 14>

cnt = 3

check[노드 2] = 3

check[노드 1] = 1 이므로 앞므로 방문할 노드 1의 check[노드 1]의 값이 더 작음


<fig 15>

cnt = 4

check[노드 4] = 4

check[노드 7] = 5

check[노드 6] = 6


노드 6은 노드 4를 재 방문

check[노드 6] = 6

check[컴포넌트 시작점 즉, 노드 4] = 4

team = 6 - 4 + 1 = 3


<fig 16>

cnt = 7

check[노드 5] = 7


노드 5는 노드 3을 재방문

check[노드 5] = 7

check[노드 3] = 2


3. 시간복잡도

- 방법 1. O(n)


- 방법 2. O(2n)


- 방법 3. O(n)


4. 회고

- 음 첫번째꺼는 인터넷에서 줍줍


- 두번째는 스스로 고민


- 세번째는 맞춘 후에 맞은사람 꺼 봄


- 세번째 방법같은 생각은 어떻게 하지...



소스코드 : 방법 1


소스코드 : 방법 2


소스코드 : 방법 3



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 4963 섬의 개수  (0) 2018.02.08
BOJ 14890 경사로  (0) 2018.02.07
BOJ 14891 톱니바퀴  (0) 2018.02.05
BOJ 2331 반복수열  (0) 2018.01.30
BOJ 10451 순열 사이클  (0) 2018.01.30

문제출처 : https://www.acmicpc.net/problem/14891


1. 문제요약

- 8개의 톱니를 가진 4개의 톱니바퀴

- 특정 하나의 톱니바퀴를 시계, 반시계 방향으로 회전

- 마주보고 있는 톱니의 극이 반대이면 옆 톱니바퀴도 같이 회전함


2. 접근방법

- 시뮬레이션


3. 시간복잡도


4. 회고

- 시뮬레이션이 제일 귀찮아


- 톱니 회전을 재귀로 구현했는데... 현재 톱니바퀴를 굴리기 전에 좌우 살펴서 돌릴 수 있으면 재귀

  재귀가 끝난 뒤 현재 톱니바퀴 회전

  재귀가 무한루프에 빠지지 않도록 톱니바퀴에 check를 넣어서 돌린적이 있는지 없는지 확인

  이런식으로 했는데


- for문으로 할 수 있는 방법도 있네

  돌리는 톱니바퀴가 결정되면 좌우에 있는 톱니바퀴는 어디로 돌릴지 방향에 대한 정보를 dir[4]에 각각 저장

  톱니바퀴 4개를 돌면서 저장된 방향대로 톱니바퀴를 회전



소스코드


소스코드 : for문



[출처 : BOJ, 문제에 대한 모든 권리는 BOJ(acmicpc.net, startlink)에 있음]

'먹고살려면 > boj' 카테고리의 다른 글

BOJ 14890 경사로  (0) 2018.02.07
BOJ 9466 텀 프로젝트  (0) 2018.02.06
BOJ 2331 반복수열  (0) 2018.01.30
BOJ 10451 순열 사이클  (0) 2018.01.30
BOJ 1707 이분 그래프  (0) 2018.01.29

+ Recent posts