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

for-each문을 돌리면서 조건에 맞으면 리스트의 요소를 삭제해주는 부분에서 java.util.ConcurrentModificationException이라며 런타임 에러가 났다.

 

오류난 부분의 코드는 다음과 같다.

이 에러는 딱 보자마자 원인이 짐작이 갔다.

 

예를 들어 처음에 list라는 리스트의 크기가 10이었다고 하자.

그러면 for-each문은 인덱스 0부터 9까지 반복하면서, 즉 list.get(0)부터 list.get(9)까지 반복하면서 일을 처리할 것이다.

그런데 인덱스 4에서 조건이 맞아서 list.get(4)를 삭제하면 이제 리스트의 크기는 9가 되고 마지막 원소는 list.get(8)이 된다. 그런데 list.get(9)를 하려고 하니까 인덱스의 범위를 넘어서면서 문제가 발생하는 것이다.

 

이 문제는 다음과 같은 방법으로 해결이 가능하다.

 

int size = list.size();
for(int i = 0; i < size(); i++)

for-each문이 아닌 for문을 직접 돌리는데 i < list.size()까지가 아니라 size라는 변수를 선언하고 i < size까지 돌린다.

if문에 해당되어 원소를 지운 경우는 i와 size를 하나씩 줄여준다.

int size = list.size();
for(int i = 0; i < size; i++) {
	리스트의 타입 element = list.get(i);
	if(조건) {
    		list.remove(element);
        	size--;
        	i--;
    	}
}

이렇게 말이다.

그러면 에러가 해결된다.

728x90
728x90

SearchView를 만들어서 OnClickListener를 등록했는데 서치뷰를 클릭해도 onClick 메소드는 호출되지 않았다. 로그캣으로 찍어봐도 아예 호출이 되지 않았다.

 

알고보니 SearchView는 setOnClickListener가 아니라 setSearchClickListener라는 것이 있었다. 이것으로 리스너를 등록했더니 해결됐다.

728x90
728x90

Retrofit2로 서버와 통신을 하는 부분이 실행이 안 되길래 onFailure 메소드에서 로그캣으로 메시지를 찍어보았다.

그랬더니 JSON forbids NaN and infinities: NaN at line 1 column 6 path $ 이런 에러가 났다.

 

그래서 저 API가 정의되어 있는 서버 부분에서 뭘 리턴하는지 찍어보았다.

그랬더니 sum / count를 리턴하는 메소드인데 sum / count가 NaN이었다.

 

그래서 서버 부분을 다음과 같이 수정해주었다.

이렇게 수정하고 나니 이제 더 이상 NaN을 리턴하지 않고 0.0을 리턴하므로 안드로이드 Retrofit을 사용하는 부분에서 onFailure 메소드로 들어가지 않고 onResponse 메소드로 들어간다.

 

서버 개발과 앱 개발을 모두 내가 하니 이렇게 오류가 생겼을 때 바로 바로 해결할 수 있어서 좋은 것 같다.

728x90
728x90

오늘도 안드로이드 개발을 하다가

java.lang.IndexOutOfBoundsException:Inconsistency detected. Invalid view holder adapter positionMyViewHolder{152d0dc position=5 id=-1, oldPos=-1, androidx.recyclerview.widget.RecyclerView

 

이런 에러가 났다.

 

SwipeRefreshLayout을 썼는데 당겨서 새로고침을 하고나면 앱이 죽으면서 저 에러가 났다.

 

구글링을 하다가 https://stackoverrun.com/ko/q/12042505

 

RecyclerView 및 java.lang.IndexOutOfBoundsException 잘못된 뷰 홀더 어댑터 positionViewHolder

식료품 품목을 바인딩하는 리사이클 러 뷰가 있습니다. 항목을 추가하면 완벽하게 작동합니다. 그러나 항목을 삭제하려고하면 응용 프로그램이 충돌하고 IndexOutOfBoundsException 오류가 발생합니다

stackoverrun.com

이 글을 발견했다.

 

이렇게 인자로 넘어온 position을 그대로 썼었는데

int safePosition = holder.getAdapterPosition();

이렇게 선언하고

이렇게 safePosition을 쓰니까 해결됐다.

 

728x90

+ Recent posts