728x90

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

 

1987번: 알파벳

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다. 말은 상하좌우로 인접한 네 칸 중의 한 칸으

www.acmicpc.net

재귀로 순열, 조합 풀듯이 풀었다. 방문한 뒤에 다시 visited를 false로 바꿔주었다. 한 번 방문했다고 다시 방문을 못하면 그것은 백트래킹이 아니라 DFS이기 때문이다.

#include <vector>
#include <algorithm>
#include <iostream>
#include <map>

using namespace std;

int dr[] = { 1, -1, 0, 0 };
int dc[] = { 0, 0, 1, -1 };
int n, m;
vector<vector<char>> v;
int maxNum = 0;
vector<bool> visited(26);

void dfs(int r, int c, int num) {
	if (num> maxNum)
		maxNum = num;
	for (int i = 0; i < 4; i++) {
		int row = r + dr[i];
		int col = c + dc[i];
		if (row >= n || col >= m || row < 0 || col < 0 || visited[v[row][col] - 'A'])
			continue;
		visited[v[row][col] - 'A'] = true;
		dfs(row, col, num + 1);
		visited[v[row][col] - 'A'] = false;
		
	}
}

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	cin >> n >> m;
	v = vector<vector<char>>(n, vector<char>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> v[i][j];
		}
	}
	visited[v[0][0] - 'A'] = true;
	dfs(0, 0, 1);
	cout << maxNum;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2023번 신기한 소수  (0) 2020.09.01
[백준] 10819번 차이를 최대로  (0) 2020.08.31
[백준] 15683번 감시  (0) 2020.08.30
[백준] 15686 치킨 배달  (0) 2020.08.30
[백준] 2636 치즈  (0) 2020.08.29
728x90

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

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감��

www.acmicpc.net

조합(combination)으로 일단 각 cctv의 방향을 정해주었고 그 다음에 cctv가 감시할 수 있는 영역을 -1로 표시해주었다. 감시할 수 있는 영역을 표시해주는 것은 spread라는 함수를 만들어서 표시해줄 수 있도록 했다. 

이것도 완전 노가다 문제였다.

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

int numOfCctv;
vector<char> cctv[6]; //1~5만 씀
int minSquare = 64;
vector<pair<int, int>> cctvLocation;
vector<int> cctvInfo;
vector<vector<int>> v;
int n, m;

void spread(vector<vector<int>>& office, int row, int col, char c) {
	if (c == 'e') {
		while (true) {
			if (col + 1 < m && office[row][++col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
	else if (c == 'w') {
		while (true) {
			if (col - 1 >= 0 && office[row][--col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
	else if (c == 's') {
		while (true) {
			if (row + 1 < n && office[++row][col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
	else if (c == 'n') {
		while (true) {
			if (row - 1 >= 0 && office[--row][col] != 6) {
				if (office[row][col] != 0)
					continue;
				office[row][col] = -1;
			}
			else break;
		}
	}
}

int getArea(vector<char> result) {
	vector<vector<int>> office(n, vector<int>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			office[i][j] = v[i][j];
		}
	}
	for (int i = 0; i < result.size(); i++) {
		int row = cctvLocation[i].first;
		int col = cctvLocation[i].second;
		if (cctvInfo[i] == 1) {
			spread(office, row, col, result[i]);
		}
		else if (cctvInfo[i] == 2) {
			if (result[i] == 'h') {
				spread(office, row, col, 'e');
				spread(office, row, col, 'w');
			}
			else if (result[i] == 'v') {
				spread(office, row, col, 's');
				spread(office, row, col, 'n');
			}
		}
		else if (cctvInfo[i] == 3) {
			if (result[i] == 'e') {
				spread(office, row, col, 'e');
				spread(office, row, col, 's');
			}
			else if (result[i] == 'w') {
				spread(office, row, col, 'w');
				spread(office, row, col, 'n');
			}
			else if (result[i] == 's') {
				spread(office, row, col, 's');
				spread(office, row, col, 'w');
			}
			else if (result[i] == 'n') {
				spread(office, row, col, 'n');
				spread(office, row, col, 'e');
			}
		}
		else if (cctvInfo[i] == 4) {
			if (result[i] == 'e') {
				spread(office, row, col, 'n');
				spread(office, row, col, 'e');
				spread(office, row, col, 's');
			}
			else if (result[i] == 'w') {
				spread(office, row, col, 's');
				spread(office, row, col, 'w');
				spread(office, row, col, 'n');
			}
			else if (result[i] == 's') {
				spread(office, row, col, 'e');
				spread(office, row, col, 's');
				spread(office, row, col, 'w');
			}
			else if (result[i] == 'n') {
				spread(office, row, col, 'w');
				spread(office, row, col, 'n');
				spread(office, row, col, 'e');
			}
		}
		else if (cctvInfo[i] == 5) {
			spread(office, row, col, 'w');
			spread(office, row, col, 'n');
			spread(office, row, col, 'e');
			spread(office, row, col, 's');
		}
	}

	int countZero = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (office[i][j] == 0)
				countZero++;
		}
	}
	return countZero;
}

void combination(vector<char> result, int num) {
	if (num == numOfCctv) {
		int area = getArea(result);
		if (area < minSquare)
			minSquare = area;
		return;
	}
	if (cctvInfo[num] == 1) {
		for (int i = 0; i < cctv[1].size(); i++) {
			result[num] = cctv[1][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 2) {
		for (int i = 0; i < cctv[2].size(); i++) {
			result[num] = cctv[2][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 3) {
		for (int i = 0; i < cctv[3].size(); i++) {
			result[num] = cctv[3][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 4) {
		for (int i = 0; i < cctv[4].size(); i++) {
			result[num] = cctv[4][i];
			combination(result, num + 1);
		}
	}
	else if (cctvInfo[num] == 5) {
		result[num] = 'a';
		combination(result, num + 1);
	}
}

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	cctv[1] = {'e', 'w', 's', 'n'};
	cctv[2] = { 'h', 'v' }; //horizontal, vertical
	cctv[3] = { 'e', 'w', 's', 'n' };
	cctv[4] = { 'e', 'w', 's', 'n' };
	cctv[5] = { 'a' };
	cin >> n >> m;
	v = vector<vector<int>>(n, vector<int>(m));
	int temp;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> temp;
			v[i][j] = temp;
			if (temp != 0 && temp != 6) {
				numOfCctv++;
				cctvLocation.push_back(make_pair(i, j));
				cctvInfo.push_back(temp);
			}
		}
	}
	combination(vector<char>(numOfCctv), 0);
	cout << minSquare;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 10819번 차이를 최대로  (0) 2020.08.31
[백준] 1987번 알파벳  (0) 2020.08.30
[백준] 15686 치킨 배달  (0) 2020.08.30
[백준] 2636 치즈  (0) 2020.08.29
[백준] 2668번 숫자고르기  (0) 2020.08.29
728x90

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

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸

www.acmicpc.net

문제를 보자마자 그냥 조합(combination)으로 풀면 안 되려나? 하는 생각을 했는데 문제의 조건에 M(1 ≤ M ≤ 13)을 보자마자 이건 조합으로 푸는게 맞구나 하고 확신했다. 그렇게 노가다로 풀었다. (브루트포스)

재귀함수 안에 3중 for문도 있어서 걱정했는데 8ms가 나왔다.

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

int n, m;
int numOfStore;
vector<vector<int>> v;
vector<pair<int, int>> storeLocation;
int minLength = 100000;

void combination(vector<int> result, vector<bool> visited, int num) {
	if (num == m) {
		int row, col;
		int sum = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (v[i][j] == 1) {
					int minLen = 1000;
					int length;
					for (int s = 0; s < m; s++) {
						row = storeLocation[result[s]].first;
						col = storeLocation[result[s]].second;
						length = ((row - i > i - row) ? row - i : i - row) + ((col - j > j - col) ? col - j : j - col);
						if (length < minLen)
							minLen = length;
					}
					sum += minLen;
				}
			}
		}
		if (sum < minLength)
			minLength = sum;
		return;
	}
	for (int i = 0; i < storeLocation.size(); i++) {
		if (!visited[i]) {
			if (num == 0) {
				result[num] = i;
				visited[i] = true;
				combination(result, visited, num + 1);
				visited[i] = false;
			}
			else {
				if (result[num - 1] < i) {
					result[num] = i;
					visited[i] = true;
					combination(result, visited, num + 1);
					visited[i] = false;
				}
			}
		}
	}
}

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	cin >> n >> m;
	v = vector<vector<int>>(n, vector<int>(n));
	int temp;
	numOfStore = 0;
	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> temp;
			v[i][j] = temp;
			if (temp == 2) {
				numOfStore++;
				storeLocation.push_back(make_pair(i, j));
			}
		}
	}
	combination(vector<int>(m), vector<bool>(numOfStore, false), 0);
	cout << minLength;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1987번 알파벳  (0) 2020.08.30
[백준] 15683번 감시  (0) 2020.08.30
[백준] 2636 치즈  (0) 2020.08.29
[백준] 2668번 숫자고르기  (0) 2020.08.29
[백준] 3190번 뱀  (0) 2020.08.29
728x90

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

 

2636번: 치즈

첫째 줄에는 사각형 모양 판의 세로와 가로의 길이가 양의 정수로 주어진다. 세로와 가로의 길이는 최대 100이다. 판의 각 가로줄의 모양이 윗 줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진��

www.acmicpc.net

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

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n, m;
	int cnt = 0;
	vector<int> countVector;
	cin >> n >> m;
	int temp;
	vector<vector<int>> v(n, vector<int>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> temp;
			v[i][j] = temp;
			if (v[i][j] == 1) {
				cnt++;
			}
		}
	}
	countVector.push_back(cnt);
	int hour = 0;
	vector<vector<bool>> visited(n, vector<bool>(m));
	stack<pair<int, int>> s;
	s.push(make_pair(0, 0));
	while (!s.empty()) {
		pair<int, int> cur = s.top();
		s.pop();
		int row = cur.first;
		int col = cur.second;
		if (!visited[row][col]) {
			visited[row][col] = true;
			v[row][col] = -1;
			if (row + 1 < n && v[row + 1][col] == 0) {
				s.push(make_pair(row + 1, col));
			}
			if (row - 1 >= 0 && v[row - 1][col] == 0) {
				s.push(make_pair(row - 1, col));
			}
			if (col + 1 < m && v[row][col + 1] == 0) {
				s.push(make_pair(row, col + 1));
			}
			if (col - 1 >= 0 && v[row][col - 1] == 0) {
				s.push(make_pair(row, col - 1));
			}
		}

	}

	while (true) {
		hour++;
		for (int i = 1; i < n - 1; i++) {
			for (int j = 1; j < m - 1; j++) {
				if (v[i][j] == 1 && (v[i + 1][j] == -1 || v[i - 1][j] == -1 || v[i][j + 1] == -1 || v[i][j - 1] == -1)) {
					v[i][j] = 2;
				}
			}
		}

		for (int i = 1; i < n - 1; i++) {
			for (int j = 1; j < m - 1; j++) {
				if (v[i][j] == 2) {
					v[i][j] = -1;
				}
			}
		}
	
		cnt = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (v[i][j] == 1) {
					cnt++;
				}
			}
		}
		if (cnt == 0)
			break;
		countVector.push_back(cnt);
		visited = vector<vector<bool>>(n, vector<bool>(m));
		s.push(make_pair(0, 0));
		while (!s.empty()) {
			pair<int, int> cur = s.top();
			s.pop();
			int row = cur.first;
			int col = cur.second;
			if (!visited[row][col]) {
				visited[row][col] = true;
				v[row][col] = -1;
				if (row + 1 < n && v[row + 1][col] != 1) {
					s.push(make_pair(row + 1, col));
				}
				if (row - 1 >= 0 && v[row - 1][col] != 1) {
					s.push(make_pair(row - 1, col));
				}
				if (col + 1 < m && v[row][col + 1] != 1) {
					s.push(make_pair(row, col + 1));
				}
				if (col - 1 >= 0 && v[row][col - 1] != 1) {
					s.push(make_pair(row, col - 1));
				}
			}

		}

	}
	cout << hour << '\n';
	cout << countVector[countVector.size() - 1];
	return 0;
}

DFS로 풀었다.  치즈 있는 부분은 1, 아무것도 없는 부분은 -1, 치즈의 구멍은 0, 녹아 없어질 치즈의 테두리 부분은 2로 표시했다. 주의해야 할 것은 1시간만에 치즈가 녹아 없어질 경우 초기에 주어진 치즈의 면적을 출력해야 하므로 미리 구해놓아야 한다는 것이다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 15683번 감시  (0) 2020.08.30
[백준] 15686 치킨 배달  (0) 2020.08.30
[백준] 2668번 숫자고르기  (0) 2020.08.29
[백준] 3190번 뱀  (0) 2020.08.29
[백준] 13335번 트럭  (0) 2020.08.16
728x90

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

 

2668번: 숫자고르기

세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절�

www.acmicpc.net

처음에는 combination으로 모든 조합을 다 구해봤다. 당연히 시간초과가 났다. N이 100 이하니까 당연한 결과였다.

 

그래서 다시 생각한 방법이 일단 map을 만들었다. key 값을 1~N까지로 하고 둘째 줄에 들어있는 값들을 value로 해서 넣었다.

그 다음에 i = 1부터 시작해서 i = N까지 반복을 하였다. 예를 들어 i = 1이라면 map[1]에 있는 value를 key에 대입하여 이제 map[1]이 key가 된다. 그 다음에 또 그 key를 가지고 map[key]로 간다. 그 다음에도 또 반복을 하는 것이다. 그런데 이미 방문했던 곳이라면 사이클이 생겼거나 숫자가 중복된다는 것이다. 숫자가 중복됐다는 것은 잘못된 것이다. 왜냐하면 첫번째 줄은 1부터 N이므로 숫자가 중복될 수가 없다. 사이클이 생긴 곳은 visited에 방문했다고 표시한다. 이런 식으로 사이클이 생긴 것들끼리 합치면 정답이 된다. 예를 들어 i = 5일 때 map[5]에 들어있는 숫자가 5라도 이것은 사이클이 발생한 것이다.

 

주어진 정수들이 3, 1, 1, 5, 5, 4, 6일 때 tempVisited와 map은 다음과 같다.

이런 식으로 i=7까지 반복하면 된다.

visited가 true인 것들이 정답이다.

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


int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	map<int, int> m;
	int temp;
	for (int i = 1; i <= n; i++) {
		cin >> temp;
		m[i] = temp;
	}
	vector<int> answer;
	vector<int> real;
	vector<bool> visited(n + 1, false);
	for (int i = 1; i <= n; i++) {
		vector<bool> tempVisited(n + 1, false);
		int key = i;
		answer.clear();
		if (!visited[i]) {
			while (true) {
				tempVisited[key] = true;
				key = m[key];
				answer.push_back(key);
				if (tempVisited[key]) {
					if (key != i) {
						answer.clear();
					}
					break;
				}
			}
		}

		for (int i = 0; i < answer.size(); i++) {
			int index = answer[i];
			visited[index] = true;
		}
	}
	for (int i = 1; i <= n; i++) {
		if (visited[i]) {
			real.push_back(i);
		}
	}
	sort(real.begin(), real.end());
	cout << real.size() << '\n';
	for (int i = 0; i < real.size(); i++) {
		cout << real[i] << '\n';
	}
	return 0;
}

 for문 안에서의 방문했는지 아닌지는 tempVisited에 저장했고 전체에서 방문했는지 아닌지 즉 정답을 체크하는 것은 visited에 저장했다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 15686 치킨 배달  (0) 2020.08.30
[백준] 2636 치즈  (0) 2020.08.29
[백준] 3190번 뱀  (0) 2020.08.29
[백준] 13335번 트럭  (0) 2020.08.16
[백준] 1051번 숫자 정사각형  (0) 2020.08.16
728x90

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

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

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


int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n, k, l; //n은 보드의 크기, k는 사과의 개수, l은 방향 변환 횟수
	cin >> n >> k;
	vector<vector<int>> v(n, vector<int>(n));
	int row, col;
	for (int i = 0; i < k; i++) {
		cin >> row >> col;
		v[row - 1][col - 1] = 1; //사과는 1 몸은 2
	}
	cin >> l;
	int second;
	char c;
	queue <pair<int, char>> q;
	for (int i = 0; i < l; i++) {
		cin >> second >> c;
		if (c == 'D') {
			q.push(make_pair(second, 'r')); //오른쪽
		}
		else {
			q.push(make_pair(second, 'l')); //왼쪽
		}
	}
	v[0][0] = 2;
	int index = 0;
	row = 0;
	col = 0;
	char direction[4] = { 'e', 's', 'w', 'n' }; //동, 남, 서, 북
	second = 0;
	/*cout << second << "초" << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cout << v[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;*/
	queue<pair<int, int>> tailQueue;
	tailQueue.push(make_pair(0, 0));
	while (true) {
		second++;
		if (!q.empty() && q.front().first + 1 == second) {
			pair<int, char> p = q.front();
			q.pop();
			if (p.second == 'r') {
				index = (index + 1) % 4;
			}
			else {
				index = (index - 1 + 4) % 4;
			}

		}
		if (direction[index] == 'e') {
			if (col + 1 >= n) {
				break;
			}
			col++;
			if (v[row][col] == 2) { //자기 자신이랑 박으면
				break;
			}
			if (v[row][col] == 1) { //사과가 있으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
			}
			else { //사과가 없으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
				pair<int, int> tail = tailQueue.front();
				tailQueue.pop();
				v[tail.first][tail.second] = 0;
			}
		}
		else if (direction[index] == 's') { //남쪽
			if (row + 1 >= n) {
				break;
			}
			row++;
			if (v[row][col] == 2) {
				break;
			}
			if (v[row][col] == 1) { //사과가 있으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
			}
			else { //사과가 없으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
				pair<int, int> tail = tailQueue.front();
				tailQueue.pop();
				v[tail.first][tail.second] = 0;
			}
		}
		else if (direction[index] == 'w') {
			if (col - 1 < 0) {
				break;
			}
			col--;
			if (v[row][col] == 2) { //자기자신과 부딪히면
				break;
			}
			if (v[row][col] == 1) { //사과가 있으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
			}
			else { //사과가 없으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
				pair<int, int> tail = tailQueue.front();
				tailQueue.pop();
				v[tail.first][tail.second] = 0;
			}
		}
		else if (direction[index] == 'n') {
			if (row - 1 < 0) {
				break;
			}
			row--;
			if (v[row][col] == 2) { //자기자신과 부딪히면
				break;
			}
			if (v[row][col] == 1) { //사과가 있으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
			}
			else { //사과가 없으면
				v[row][col] = 2;
				tailQueue.push(make_pair(row, col));
				pair<int, int> tail = tailQueue.front();
				tailQueue.pop();
				v[tail.first][tail.second] = 0;
			}
		}
		/*cout << second << "초" << endl;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				cout << v[i][j] << " ";
			}
			cout << endl;
		}
		cout << endl;*/
	}
	cout << second;
	return 0;
}

시작으로부터 x초라는 것을 몰라서 계속 정답과 같거나 정답과 1만큼 차이나서 애를 먹었다.

그러니까 초기에는 즉, 0초에는 1행 1열에 있고 시작으로부터 1초 후인 1초 시점에 머리는 1행 2열에 있다는 것이다.

이걸 아래 글을 읽고서야 알게 되었다.

https://www.acmicpc.net/board/view/13898

 

글 읽기 - 같은걸로 고민하시는 분 있을까봐 올립니다.

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 

코드 설명을 하자면 몇

초에 어느 방향으로 회전할지는 q라는 이름의 큐에 (몇 초, 어느 방향)의 쌍으로 묶어서 담았다.

꼬리를 삭제할 때 꼬리의 위치도 필요하기 때문에 tailQueue라는 것도 만들었다. 한 칸 앞으로 갈 때마다 방문하는 위치를 tailQueue에 (행, 열) 쌍으로 묶어서 집어넣었고 한 칸 앞으로 당길 때마다 tailQueue에서 빼서 그 위치는 0으로 만들어주었다.

사과의 위치는 1로 표시했고 뱀의 위치는 2로 표시했다. 사과는 한 번 먹으면 없어지니까 뱀이 지나간 자리는 0으로 만들어주었다.

 

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2636 치즈  (0) 2020.08.29
[백준] 2668번 숫자고르기  (0) 2020.08.29
[백준] 13335번 트럭  (0) 2020.08.16
[백준] 1051번 숫자 정사각형  (0) 2020.08.16
[프로그래머스] 행렬의 곱셈  (0) 2020.08.01
728x90

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

 

13335번: 트럭

문제 강을 가로지르는 하나의 차선으로 된 다리가 하나 있다. 이 다리를 n 개의 트럭이 건너가려고 한다. 트럭의 순서는 바꿀 수 없으며, 트럭의 무게는 서로 같지 않을 수 있다. 다리 위에는 단��

www.acmicpc.net

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

int main() {
	cin.tie(NULL);
	int n, w, l;
	cin >> n >> w >> l;
	vector<int> v(n);
	queue<int> q;
	vector<int> count;
	for (int i = 0; i < n; i++) {
		cin >> v[i];
	}
	q.push(v[0]);
	count.push_back(w);
	int index = 1;
	int time = 1;
	int totalWeight = v[0];
	int weight;
	while (!q.empty()) {
		for (int i = 0; i < count.size(); i++) {
			count[i]--;
		}
		if (count[0] == 0) {
			weight = q.front();
			q.pop();
			totalWeight -= weight;
			count.erase(count.begin());
		}
		if (index < n && totalWeight + v[index] <= l) {
			q.push(v[index]);
			count.push_back(w);
			totalWeight += v[index];
			index++;
		}
		time++;
	}
	cout << time;
	return 0;
}

q라는 이름으로 큐를 하나 만들어놓고 다리에 진입한 트럭들은 큐에 집어넣었다. 그리고 큐에 들어간 트럭들의 무게들은 totalWeight에 더해주었다. 트럭이 다리에서 벗어나면 즉, 큐에서 빠지게 되면 totalWeight에서도 트럭의 무게만큼 빼주었다.

그리고 트럭이 단위시간에 단위길이만큼만 이동하기 때문에 다리에 진입한 트럭 하나마다 얼마나 더 가야하는지 남은 길이(남은 시간)를 count라는 벡터에 저장해주었다. 당연히 처음에는 다리의 길이이고 단위시간이 지날 때마다 count[i]--로 1씩 빼주었다. count[i]가 0이 되는 순간 큐에서 트럭을 빼고 count[i]도 벡터에서 제거해주었다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2668번 숫자고르기  (0) 2020.08.29
[백준] 3190번 뱀  (0) 2020.08.29
[백준] 1051번 숫자 정사각형  (0) 2020.08.16
[프로그래머스] 행렬의 곱셈  (0) 2020.08.01
[프로그래머스] 기능개발  (0) 2020.07.31
728x90

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

 

1051번: 숫자 정사각형

N*M크기의 직사각형이 있다. 각 칸은 한 자리 숫자가 적혀 있다. 이 직사각형에서 꼭짓점에 쓰여 있는 수가 모두 같은 가장 큰 정사각형을 찾는 프로그램을 작성하시오. 이때, 정사각형은 행 또는

www.acmicpc.net

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

int main() {
	cin.tie(NULL);
	int n, m;
	cin >> n >> m;
	vector<vector<int>> v(n, vector<int>(m));
	int length = min(n, m) - 1;
	string s;
	for (int i = 0; i < n; i++) {
		cin >> s;
		for (int j = 0; j < m; j++) {
			v[i][j] = stoi(s.substr(j, 1));
		}
	}
	bool flag = false;
	while (true) {
		for (int row = 0; row + length < n; row++) {
			for (int col = 0; col + length < m; col++) {
				if (v[row][col] == v[row + length][col] && v[row][col] == v[row][col + length] && v[row][col] == v[row + length][col + length]) {
					flag = true;
					break;
				}
			}
			if (flag)
				break;
		}
		if (flag) break;
		length--;
	
	}
	cout << (length + 1) *(length + 1);
	return 0;
}

네모칸을 점점 줄여가면서 이동시키면서 네 꼭짓점의 값이 같은 정사각형을 발견해나가면 된다.

변의 길이는 가로, 세로의 길이 중 짧은 것으로 시작한다. (그것을 length로 뒀다)

기준이 되는 점인 (row, col)을 왼쪽에서 오른쪽으로, 위에서 아래로 옮겨가면서 네 칸의 값이 같을 때까지 반복한다.

끝까지 갔는데 발견되지 않으면 length를 줄이고 그것을 반복한다.

주의할 점은 변의 길이가 3이면 세 칸을 차지하는 것이니까 0~3이 아니라 0~2라는 것이다. 따라서 변의 길이가 3이면 length를 2가 되게 했다. row + length 했을 때 두 칸을 더해야 되니까. 그리고나서 나중에 크기를 구할 때에는 length에 1을 더해주었다. 

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 3190번 뱀  (0) 2020.08.29
[백준] 13335번 트럭  (0) 2020.08.16
[프로그래머스] 행렬의 곱셈  (0) 2020.08.01
[프로그래머스] 기능개발  (0) 2020.07.31
[프로그래머스] 큰 수 만들기  (0) 2020.07.30
728x90

https://programmers.co.kr/learn/courses/30/lessons/12949

 

코딩테스트 연습 - 행렬의 곱셈

[[2, 3, 2], [4, 2, 4], [3, 1, 4]] [[5, 4, 3], [2, 4, 1], [3, 1, 1]] [[22, 22, 11], [36, 28, 18], [29, 20, 14]]

programmers.co.kr

#include <string>
#include <vector>

using namespace std;

vector<vector<int>> solution(vector<vector<int>> arr1, vector<vector<int>> arr2) {
	int row = arr1.size();
	int col = arr2[0].size();
	int t = arr1[0].size();
	int n;
	vector<vector<int>> answer(row, vector<int>(col));
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			n = 0;
			for (int k = 0; k < t; k++) {
				n += (arr1[i][k] * arr2[k][j]);
			}
			answer[i][j] = n;
		}
	}
	return answer;
}

행렬의 곱셈을 그대로 구현하면 된다. 3중 for문이라서 약간 헷갈렸지만 공책에 표시하면서 풀었더니 금방 쉽게 풀 수 있었다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 13335번 트럭  (0) 2020.08.16
[백준] 1051번 숫자 정사각형  (0) 2020.08.16
[프로그래머스] 기능개발  (0) 2020.07.31
[프로그래머스] 큰 수 만들기  (0) 2020.07.30
[프로그래머스] 땅따먹기  (0) 2020.07.30
728x90

https://programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 ��

programmers.co.kr

#include <string>
#include <vector>
#include <cmath>

using namespace std;

vector<int> solution(vector<int> progresses, vector<int> speeds) {
	vector<int> answer;
	int n = ceil((100 - progresses[0]) / (double)speeds[0]);
	int num = 1;
	for (int i = 1; i < progresses.size(); i++) {
		if (ceil((100 - progresses[i]) / (double)speeds[i]) <= n) {
			num++;
		}
		else {
			answer.push_back(num);
			num = 1;
			n = ceil((100 - progresses[i]) / (double)speeds[i]);
		}
	}
	answer.push_back(num);
	return answer;
}

비주얼 스튜디오에서는 <cmath> 헤더를 포함해주지 않아도 잘 돌아갔지만 프로그래머스에 제출할 때에는 돌아가지 않았다. ceil 함수를 사용할 때에는 <cmath>를 포함하자.

그냥 문제에 있는 그대로 구현해주면 된다.

728x90

+ Recent posts