반응형

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

 

8983번: 사냥꾼

입력의 첫 줄에는 사대의 수 M (1 ≤ M ≤ 100,000), 동물의 수 N (1 ≤ N ≤ 100,000), 사정거리 L (1 ≤ L ≤ 1,000,000,000)이 빈칸을 사이에 두고 주어진다. 두 번째 줄에는 사대의 위치를 나타내는 M개의 x-좌

www.acmicpc.net

#include <bits/stdc++.h>
using namespace std;

vector<int> gun;


bool distance(int x, int y, int L) {

	bool ans = false;
	if (y > L) return false;

	int s = 0;
	int e = gun.size() - 1;

	while (s <= e) {

		int mid = (s + e) / 2;

		if (abs(gun[mid] - x) + y <=L) {
			ans = true;
			break;
		}
		else if (gun[mid] > x) {
			e = mid - 1;
		}
		else {
			s = mid + 1;
		}
	}


	return ans;
}


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int m, n, l;
	cin >> m >> n >> l;
	

	for (int i = 0; i < m; i++) {
		int tmp;
		cin >> tmp;
		gun.push_back(tmp);
	}

	sort(gun.begin(), gun.end());

	int cnt = 0;
	for (int i = 0; i < n; i++) {
		int x, y;
		cin >> x >> y;
		if (distance(x, y ,l)) cnt++;
	}

	cout << cnt << '\n';


	

	return 0;
}

백준 8983번

반응형
반응형

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

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을

www.acmicpc.net

접근방법[알고리즘]

1. 빙산이 몇개의 덩어리로 이루어져있는지 BFS를 이용해 개수를 센다.

2. 빙산의 개수가 2개이상이거나 0이 아니면 빙산을 한차례 녹인다.

3. 1과 2를 반복한다.

 


주의할 점

빙산이 녹아 없어지는 경우 바로 0으로 만들어버리면
다음 빙산에 영향을 줘서 틀린다.
빙산이 0이 되는 경우는 따로 저장해뒀다가 큐를 한바퀴 다 돈다음
적용 해주어야 한다.

 


문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;

int n, m, arr[301][301] ,t;
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

int Count() {
	int check[301][301];
	int ans = 1;
	memset(check, 0, sizeof(check));
	queue<pair<int, int> > Q;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (arr[i][j] > 0 && check[i][j]==0) {
				check[i][j] = ans;
				Q.push({ i,j });

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

					for (int k = 0; k < 4; k++) {
						int nx = x + dx[k];
						int ny = y + dy[k];
						if (nx < 0 || nx >= n || ny < 0 || ny >= m || arr[nx][ny] == 0) continue;
						if (check[nx][ny] == 0) {
							check[nx][ny] = ans;
							Q.push({ nx,ny });
						}
					}
				}
				ans++;
			}
		}
	}
	return ans - 1;
}


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	queue<pair<int, int> > Q;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> arr[i][j];
			if (arr[i][j] > 0) Q.push({ i,j });
		}
	}


	while (1) {
		int area = Count();
		if (area >= 2) {
			cout << t << '\n';
			return 0;
		}
		else if (area == 0) {
			cout << 0 << '\n';
			return 0;
		}

		int s = Q.size();
		//빙산이 녹아 없어지는 경우 바로 0으로 만들어버리면
		//다음 빙산에 영향을 줘서 틀린다.
		//빙산이 0이 되는 경우는 따로 저장해뒀다가 큐를 한바퀴 다 돈다음
		//적용 해주어야 한다.

		vector<pair<int, int> > melt;
		for (int i = 0; i < s; i++) {
			int x = Q.front().first;
			int y = Q.front().second;
			Q.pop();

			int cnt = 0;
			for (int j = 0; j < 4; j++) {
				int nx = x + dx[j];
				int ny = y + dy[j];
				if (nx < 0 || nx >= n || ny < 0 || ny >= m || arr[nx][ny]>0) continue;
				cnt++;
			}

			if (cnt >= arr[x][y]) {
				melt.push_back({ x,y });
			}
			else {
				arr[x][y] -= cnt;
				Q.push({ x,y });
			}
		}
		for (int i = 0; i < melt.size(); i++) {
			arr[melt[i].first][melt[i].second] = 0;
		}

		t++;
	}

	return 0;
}

백준 2573번

 

반응형
반응형

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

 

1753번: 최단경로

첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가

www.acmicpc.net

 

#include <bits/stdc++.h>
using namespace std;

int ans[20001], v, e, st;

struct Node {
	int n, d;

	bool operator<(const Node& b) const {
		return d > b.d;
	}
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	fill(ans, ans + 20001, -1);

	cin >> v >> e;
	cin >> st;

	vector<pair<int, int> > m[20001];

	for (int i = 0; i < e; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		m[a].push_back({ b,c });
	}

	priority_queue<Node> Q;
	Q.push({ st,0 });

	while (!Q.empty()) {
		int cur_node = Q.top().n;
		int cur_dist = Q.top().d;
		Q.pop();

		if (ans[cur_node] == -1) {
			ans[cur_node] = cur_dist;

			for (int i = 0; i < m[cur_node].size(); i++) {
				int nx = m[cur_node][i].first;
				if (ans[nx] == -1) {
					int nd = m[cur_node][i].second + cur_dist;
					Q.push({ nx,nd });
				}
			}
		}
	}


	for (int i = 1; i <= v; i++) {
		if (ans[i] == -1) cout << "INF\n";
		else cout << ans[i] << '\n';
	}


	return 0;
}

우선순위큐 최소힙을 이용해

다익스트라 알고리즘으로 풀 수 있다.

1753번 최단경로 메모리 및 시간

 

반응형
반응형

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

 

9935번: 문자열 폭발

첫째 줄에 문자열이 주어진다. 문자열의 길이는 1보다 크거나 같고, 1,000,000보다 작거나 같다. 둘째 줄에 폭발 문자열이 주어진다. 길이는 1보다 크거나 같고, 36보다 작거나 같다. 두 문자열은 모

www.acmicpc.net

1.문제설명

 

INPUT

12ab112ab2ab
12ab

첫 째로 일반 문자열이 주어지고

두번째로 폭발하는 문자열이 주어진다.

1. 일반 문자열 내에 폭발 문자열이 있을 경우 폭발 문자열을 없애줘야한다.

2. 폭발 문자열을 없앤 결과 또 폭발문자열이 포함되어 있을 경우 다시 폭발문자열을 없애줘야한다.

 

1과 2를 문자열 내에 폭발문자열이 없을 때까지 반복한다.

 

 

 


2.접근방법[알고리즘]

백준 문자열 폭발

그동안 습관적으로 STL을 사용하던 버릇에 긴장감을 주는 문제다.

 

스택을 직접 구현해야 가장 편하게 풀 수 있다.

 

입력받은 첫째 문자열을 돌면서 stack에 char 문자 하나씩 넣어주다가

stack의 가장 위 문자가 폭발 문자열의 마지막 문자와 동일하면

그 문자가 폭발 문자열을 이루고 있는지 확인하고,

 

폭발문자열이 발견되면 그만큼 pop 해주어야한다.

pop 해주는 건 p 변수를 폭발문자열의 크기 만큼 빼주면 쉽게 구현할 수 있다.

 

 


3.문제풀이코드 C++

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

char stack[1000001];
int p = 0;
string str;
string bomb;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> str;
	cin >> bomb;
	
	for (int i = 0; i < str.length(); i++) {
		stack[p++] = str[i];

		if (p >= bomb.length() && stack[p - 1] == bomb[bomb.length() - 1]) {
			bool is_same = true;
			for (int j = 0; j < bomb.length(); j++) {
				if (bomb[j] != stack[p - bomb.length() + j]) {
					is_same = false;
				}
			}
			if (is_same) {
				p -= bomb.length();
			}
		}
	}

	if (p == 0) {
		cout << "FRULA" << '\n';
	}
	else {
		for (int i = 0; i < p; i++) {
			cout << stack[i];
		}
		cout << '\n';
	}


	return 0;
}

백준 9935번 : 문자열 폭발

반응형
반응형

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

 

16235번: 나무 재테크

부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터

www.acmicpc.net

1.문제설명

 

봄에는 나무가 자신의 나이만큼 양분을 먹고, 나이가 1 증가한다. 각각의 나무는 나무가 있는 1×1 크기의 칸에 있는 양분만 먹을 수 있다. 하나의 칸에 여러 개의 나무가 있다면, 나이가 어린 나무부터 양분을 먹는다. 만약, 땅에 양분이 부족해 자신의 나이만큼 양분을 먹을 수 없는 나무는 양분을 먹지 못하고 즉시 죽는다.

 

여름에는 봄에 죽은 나무가 양분으로 변하게 된다. 각각의 죽은 나무마다 나이를 2로 나눈 값이 나무가 있던 칸에 양분으로 추가된다. 소수점 아래는 버린다.

가을에는 나무가 번식한다. 번식하는 나무는 나이가 5의 배수이어야 하며, 인접한 8개의 칸에 나이가 1인 나무가 생긴다.

 

겨울에는 S2D2가 땅을 돌아다니면서 땅에 양분을 추가한다. 각 칸에 추가되는 양분의 양은 A[r][c]이고, 입력으로 주어진다.

 

문제에서 설명한 단계에 맞춰서 똑같이 구현하면 됩니다.

 


2.접근방법[알고리즘]

구현과 동시에 코드 최적화가 핵심입니다.

시간제한이 0.3초여서 최대한 최적화해야 해결할 수 있습니다.

 

이 문제에서 한 칸 안에 나무 여러 개가 있을 수 있습니다.

한 칸에 나무가 여러 개 있을 경우 나이가 적은 나무 부터 양분을 섭취해야합니다.

 

이때 자연스럽게 매번마다 나무를 오름차순으로 sort한 뒤 양분을 섭취하게끔 해야겠다는 생각이 듭니다.

하지만 그러면 시간초과로 틀립니다.

 

문제 조건 상 sort는 맨 처음 한 번만 해도 풀 수 있습니다.

 

8칸에 새로 생기는 나무의 나이는 무조건 1이기 때문에

새로 생긴 나무를 맨 앞으로 보내주고

이전에 있던 나무들은 뒤로 보내주면 sort를 해주지 않아도 됩니다.

 


 

3.문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;

int n, m, k, ans, arr[11][11], added[11][11];
int dx[8] = { 1,0,-1,0,1,-1,1,-1 };
int dy[8] = { 0,1,0,-1,1,-1,-1,1 };

struct Tree {
	int x, y, age;
	bool operator<(const Tree &bb) const {
		return age < bb.age;
	}
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	vector<Tree> v;
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> added[i][j];
			arr[i][j] = 5;
		}
	}

	for (int i = 0; i < m; i++) {
		int x, y, z;
		cin >> x >> y >> z;
		v.push_back({ x,y,z });
	}

	sort(v.begin(), v.end());
	
	for (int K = 0; K < k; K++) {
		vector<Tree> new_v;

		// 봄
		for (int i = 0; i < v.size(); i++) {
			if (v[i].age == 0) continue;

			if (v[i].age <= arr[v[i].x][v[i].y]) {
				arr[v[i].x][v[i].y] -= v[i].age;
				v[i].age++;

				// 가을에 새로 생기는 나무들
				if (v[i].age % 5 == 0) {
					for (int j = 0; j < 8; j++) {
						int nx = v[i].x + dx[j];
						int ny = v[i].y + dy[j];
                        
						//new_v 벡터에 새로생기는 나무들 먼저 넣어줌
						if (nx <= 0 || nx > n || ny <= 0 || ny > n)continue;
						new_v.push_back({ nx, ny, 1 });
					}
				}
			}
			else {
            	//죽은 나무들 
				v[i].age = -v[i].age;
			}
		}

		//여름 
		for (int i = 0; i < v.size(); i++) {
        //죽은 나무들 양분으로 전환 
			if (v[i].age < 0)
			{
				arr[v[i].x][v[i].y] += (-v[i].age / 2);
			}
			else {
            //new_v에 기존에 있던 나무들 뒤로 보내줌 
				new_v.push_back(v[i]);
			}
		}

		// 겨울
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				arr[i][j] += added[i][j];
			}
		}

		v.swap(new_v);
	}


	cout << v.size() << '\n';
	return 0;
	
}

백준 16235번 시간초과 해결

 

 

 

백준 16235번: 나무 재테크 반례

이 테스트케이스가 오래 걸린다면 통과할 수 없습니다.

10 100 1000
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100 100 100
1 1 4
1 2 4
1 3 4
1 4 4
1 5 4
1 6 4
1 7 4
1 8 4
1 9 4
1 10 4
2 1 4
2 2 4
2 3 4
2 4 4
2 5 4
2 6 4
2 7 4
2 8 4
2 9 4
2 10 4
3 1 4
3 2 4
3 3 4
3 4 4
3 5 4
3 6 4
3 7 4
3 8 4
3 9 4
3 10 4
4 1 4
4 2 4
4 3 4
4 4 4
4 5 4
4 6 4
4 7 4
4 8 4
4 9 4
4 10 4
5 1 4
5 2 4
5 3 4
5 4 4
5 5 4
5 6 4
5 7 4
5 8 4
5 9 4
5 10 4
6 1 4
6 2 4
6 3 4
6 4 4
6 5 4
6 6 4
6 7 4
6 8 4
6 9 4
6 10 4
7 1 4
7 2 4
7 3 4
7 4 4
7 5 4
7 6 4
7 7 4
7 8 4
7 9 4
7 10 4
8 1 4
8 2 4
8 3 4
8 4 4
8 5 4
8 6 4
8 7 4
8 8 4
8 9 4
8 10 4
9 1 4
9 2 4
9 3 4
9 4 4
9 5 4
9 6 4
9 7 4
9 8 4
9 9 4
9 10 4
10 1 4
10 2 4
10 3 4
10 4 4
10 5 4
10 6 4
10 7 4
10 8 4
10 9 4
10 10 4

 8456​

 

반응형
반응형

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

 

1726번: 로봇

많은 공장에서 로봇이 이용되고 있다. 우리 월드 공장의 로봇은 바라보는 방향으로 궤도를 따라 움직이며, 움직이는 방향은 동, 서, 남, 북 가운데 하나이다. 로봇의 이동을 제어하는 명령어는

www.acmicpc.net

1.문제설명

백준 1726 로봇

 

명령 1. Go k: k는 1, 2 또는 3일 수 있다. 현재 향하고 있는 방향으로 k칸 만큼 움직인다

명령 2. Turn dir: dir은 left 또는 right 이며, 각각 왼쪽 또는 오른쪽으로 90° 회전한다.

 

동에서 서, 북에서 남으로 회전하는 데는 명령을 두번 해야한다

현재 방향에서 한 번의 명령으로 최대 3칸까지 이동이 가능하다.

벽을 통과할 수는 없다.

 

2.접근방법[알고리즘]

이 문제는 시작 지점에서 종료 지점 까지 가는데 필요한 최소 명령의 수를 구해야 한다.

한 번의 명령마다 방향전환을 하거나 이동을 한다.

 

특정 지점을 방문했을 때 단순히 좌표만 저장 하는 게 아니라, 방향에 대한 정보까지 저장을 해주어야한다.

그래서 이전에 방문했는지 체크해주는 배열을 3차원 배열로 만들어

vis[x][y][동 or 서 or 남 or 북] x, y 좌표에 대해서

동, 서, 남 , 북 방향 상태까지 필요햔 명령의 수를 체크해야한다.


하나의 좌표마다 행동할 수 있는 경우의 수는

현재 방향에서 1칸, 2칸, 3칸 이동하기와

현재 방향을 제외한 나머지 방향으로 방향전환 하기가 있다.

 

한 번의 명령으로 1칸 2칸 3칸 모두 이동하는 게 가능하지만,

방향을 전환 하는데는 동에서 서로 방향을 전환하거나 남에서 북으로 방향을 전환한다면 2번의 명령이 필요하다.

 

이 때 2번의 명령이 필요한 경우 방향을 전환했다고 바로 방문을 했다고 체크하는 게 아니라 

나중에 큐에서 나올 때 체크해주어야한다.

 

왜냐하면 x,y가 도착지점일 때 x,y에서 방향을 전환하는데 2번 명령을 하는 동안

다른 점에서 한번만에 도착하는 경우도 있기 때문이다.

 

 

결과적으로 도착점까지 최소 명령의 수를 구해야하기 때문에 우선순위 큐를 이용했다.

명령의 수를 최소힙으로 계속 pop해주면서 로봇이 최소 명령으로 하는 행동을 먼저하게 한다.

그러다 도착지점에 다다르면 바로 해당 도착지점에 오기까지 필요했던 명령의 수를 바로 리턴해주었다.

 

 


우선순위큐를 사용하지 않으면?

만약 우선순위큐를 사용하지 않는다면

도착지점에 도착했다고 바로 리턴해주면 안된다.

방향전환하는데 명령이 2번 일어나는 경우도 있어서

큐에서 뒤에 나오는 경우가 더 적은 명령의 수로 일어나는 행동일 수도 있기 때문이다.

즉 BFS를 돌지만 다른 문제와 다르게 큐에서 뒤에서 나오는 결과가 정답일 수도 있다.

 

 

3.문제풀이코드

첫 정답코드

#include <bits/stdc++.h>
using namespace std;

//회전시키는데 명령 1, 현재 방향에서 이동하는데 명령 1,

int n, m, arr[105][105], sx, sy, sd, ex, ey, ed, ans = INT_MAX;
bool vis[105][105][5]; //1동 2서 3남 4북 방향 정보까지 받는다 

struct Edge {
	int x, y, d, cnt;
	Edge(int a, int b, int c, int e) {
		x = a;
		y = b;
		d = c;
		cnt = e;
	}
	bool operator<(const Edge& bb) const {
		return cnt > bb.cnt;
	}
};

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	priority_queue<Edge> Q;

	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> arr[i][j];
		}
	}
	cin >> sx >> sy >> sd;
	cin >> ex >> ey >> ed;

	vis[sx][sy][sd] = 1;
	Q.push(Edge(sx, sy, sd, 0));


	while (!Q.empty()) {
		int x = Q.top().x;
		int y = Q.top().y;
		int d = Q.top().d;
		int cnt = Q.top().cnt;
		Q.pop();
		vis[x][y][d] = 1;

		//if(d==1)
		//	cout << x <<' ' << y << " " << "동" << " " << cnt<< '\n';
		//else if(d==2)
		//	cout << x << ' ' << y << " " << "서" << " " << cnt<< '\n';
		//else if (d == 3)
		//	cout << x << ' ' << y << " " << "남" << " " << cnt<< '\n';
		//else if (d == 4)
		//	cout << x << ' ' << y << " " << "북" << " " << cnt<< '\n';

		if (x == ex && y == ey && d == ed) {
			ans = min(cnt, ans);
		}

		// 현재 방향에서 이동
		// d == 1 : nx : 0 / ny : 1, 2, 3
		// d == 2 : nx : 0 / ny : -1, -2, -3;
		// d == 3 : nx: 1 , 2 , 3 / ny : 0
		// d == 4 : nx : -1 -2 -3 / ny : 0;

		if (d == 1) {
			for (int i = 1; i <= 3; i++) {
				if (y + i > m) break;
				if (arr[x][y + i] == 1) break;
				if (vis[x][y + i][d] == 0) {
					vis[x][y + i][d] = 1;
					Q.push(Edge{ x,y + i,d ,cnt + 1 });
				}
			}
		}
		else if (d == 2) {
			for (int i = 1; i <= 3; i++) {
				if (y - i < 1) break;
				if (arr[x][y - i] == 1) break;
				if (vis[x][y - i][d] == 0) {
					vis[x][y - i][d] = 1;
					Q.push(Edge{ x,y - i,d ,cnt + 1 });
				}
			}
		}
		else if (d == 3) {
			for (int i = 1; i <= 3; i++) {
				if (x + i > n) break;
				if (arr[x + i][y] == 1) break;
				if (vis[x + i][y][d] == 0) {
					vis[x + i][y][d] = 1;
					Q.push(Edge{ x + i,y,d ,cnt + 1 });
				}
			}
		}
		else if (d == 4) {
			for (int i = 1; i <= 3; i++) {
				if (x - i < 1) break;
				if (arr[x - i][y] == 1) break;
				if (vis[x - i][y][d] == 0) {
					vis[x - i][y][d] = 1;
					Q.push(Edge{ x - i,y,d ,cnt + 1 });
				}
			}
		}

		//방향전환 명령 
		for (int i = 1; i <= 4; i++) {
			if (i == d) continue;

			if (vis[x][y][i] == 0) {
				if ((d == 1 && i == 2) || (d == 2 && i == 1)) {
					Q.push(Edge(x, y, i, cnt + 2));
				}
				else if ((d == 3 && i == 4) || (d == 4 && i == 3)) {
					Q.push(Edge(x, y, i, cnt + 2));
				}
				else {
					vis[x][y][i] = 1;
					Q.push(Edge(x, y, i, cnt + 1));
				}
			}
		}
	}

	cout << ans;
	return 0;

}

 

#include <bits/stdc++.h>
using namespace std;

//회전시키는데 명령 1, 현재 방향에서 이동하는데 명령 1,

int n, m, arr[105][105], sx, sy, sd, ex, ey, ed, ans = INT_MAX;
bool vis[105][105][5]; //1동 2서 3남 4북 방향 정보까지 받는다 


struct Edge {
	int x, y, d, cnt;
	Edge(int a, int b, int c, int e) {
		x = a;
		y = b;
		d = c;
		cnt = e;
	}
	bool operator<(const Edge& bb) const {
		return cnt > bb.cnt;
	}
};

priority_queue<Edge> Q;



void move(int x, int y, int d, int cnt) {
	if (d == 1) {
		for (int i = 1; i <= 3; i++) {
			if (y + i > m) break;
			if (arr[x][y + i] == 1) break;
			if (vis[x][y + i][d] == 0) {
				vis[x][y + i][d] = 1;
				Q.push(Edge{ x,y + i,d ,cnt + 1 });
			}
		}
	}
	else if (d == 2) {
		for (int i = 1; i <= 3; i++) {
			if (y - i < 1) break;
			if (arr[x][y - i] == 1) break;
			if (vis[x][y - i][d] == 0) {
				vis[x][y - i][d] = 1;
				Q.push(Edge{ x,y - i,d ,cnt + 1 });
			}
		}
	}
	else if (d == 3) {
		for (int i = 1; i <= 3; i++) {
			if (x + i > n) break;
			if (arr[x + i][y] == 1) break;
			if (vis[x + i][y][d] == 0) {
				vis[x + i][y][d] = 1;
				Q.push(Edge{ x + i,y,d ,cnt + 1 });
			}
		}
	}
	else if (d == 4) {
		for (int i = 1; i <= 3; i++) {
			if (x - i < 1) break;
			if (arr[x - i][y] == 1) break;
			if (vis[x - i][y][d] == 0) {
				vis[x - i][y][d] = 1;
				Q.push(Edge{ x - i,y,d ,cnt + 1 });
			}
		}
	}
}

void turn_dir(int x, int y, int d, int cnt) {
	for (int i = 1; i <= 4; i++) {
		if (i == d) continue;
		if (vis[x][y][i] == 0) {
			if ((d == 1 && i == 2) || (d == 2 && i == 1)) {
				// 바로 방문 체크를 하면 안된다. 방향전환 하는 동안 먼저 방문하는 경우가 있을 수도 있다.
				Q.push(Edge(x, y, i, cnt + 2));
			}
			else if ((d == 3 && i == 4) || (d == 4 && i == 3)) {
				Q.push(Edge(x, y, i, cnt + 2));
			}
			else {
				vis[x][y][i] = 1;
				Q.push(Edge(x, y, i, cnt + 1));
			}
		}
	}
}


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);	

	//입력 
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> arr[i][j];
		}
	}
	cin >> sx >> sy >> sd;
	cin >> ex >> ey >> ed;

	vis[sx][sy][sd] = 1;
	Q.push(Edge(sx, sy, sd, 0));

	while (!Q.empty()) {
		int x = Q.top().x;
		int y = Q.top().y;
		int d = Q.top().d;
		int cnt = Q.top().cnt;
		Q.pop();
		vis[x][y][d] = 1;

		if (x == ex && y == ey && d == ed) {
			cout << cnt;
			return 0;
		}
		// 현재 방향에서 이동
		move(x, y, d, cnt);
		//방향전환 명령 
		turn_dir(x,y,d,cnt);
	}

	return 0;

}

 

 

백준 1726 메모리 및 시간 

 

 

4. 반례모음

백준 1726 로봇 문제 반례 및 테스트케이스 모음입니다.


5 6
0 0 0 0 0 0
0 1 1 0 1 0
0 1 0 0 0 0
0 0 1 1 1 0
1 0 0 0 0 0
4 2 3
1 6 2

답 : 8


42 79
0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0
0 1 0 0 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 1 0 1 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 1 1 0 0 1 0 0 1 0 0
1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 0
1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 1 1 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 1 0 1 1 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 1 1 1 1 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0
0 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 1
1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 1 0 0
1 0 0 0 0 1 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 1
1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 1 1 0 0 1 1 1 0 1 1 0 0 0 1 0 0 0
1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 0
0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0
1 1 0 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 1 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 1 1 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0
0 0 0 0 1 1 1 1 1 1 0 0 1 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0
0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 1 1 0
1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 0 1 1 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 0 0
1 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 1 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1
0 0 1 1 1 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1
1 0 0 0 0 1 1 0 0 0 0 1 0 1 0 1 0 0 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 1 0
0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 1
0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 1
0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 1 0 1 1 0 1 0 0 1 1
1 0 0 1 1 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0
0 1 0 1 0 0 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 1 1 0 0 0 1 1 0 1 0 1 0 1 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 1 1 0 1 1 1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 1 1 0 0 1 0 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1
0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 1 0 0
0 0 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 1 1 1 0 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0
0 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 1
1 1 0 1 0 0 1 0 1 0 0 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0
1 0 0 1 1 0 0 1 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 1
0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1
1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 1 1 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 0
6 77 1
36 1 3

답 : 93


5 6
0 0 0 0 0 0
0 1 1 1 1 1
0 1 0 1 0 0
0 0 0 1 1 0
0 1 0 0 0 0
1 1 1
3 5 3

답 13

 


3 3
0 0 0
0 0 0
0 0 0
1 1 2
3 3 4

답 5

 


9 12
0 0 0 0 0 0 0 0 0 0 0 1
0 1 1 1 1 0 0 1 1 1 1 0
0 0 0 0 0 0 0 1 1 1 1 0
0 1 1 1 1 0 0 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 0 0 1 1 1 1 0
0 1 1 1 1 0 0 0 0 0 0 0
0 1 1 1 1 0 0 1 1 1 1 0
1 0 0 0 0 0 0 0 0 0 0 0
1 1 3
9 12 3

답 10

 


 

반응형
반응형

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

 

14923번: 미로 탈출

홍익이는 사악한 마법사의 꾐에 속아 N x M 미로 (Hx, Hy) 위치에 떨어졌다. 다행히도 홍익이는 마법사가 만든 미로의 탈출 위치(Ex, Ey)를 알고 있다. 하지만 미로에는 곳곳에 마법사가 설치한 벽이

www.acmicpc.net

 

문제 설명

https://dingcoding.tistory.com/95

 

백준 2206번: 벽 부수고 이동하기 문제풀이 및 반례 모음

https://www.acmicpc.net/problem/2206 2206번: 벽 부수고 이동하기 N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에

dingcoding.tistory.com

백준 2206번 벽부수고 이동하기 문제와 똑같은 문제다.

 

벽을 부순 상태와 부수지 않은 상태를 나누어서 생각해야 한다.

 

설명은 위 링크를 참고

 

 

문제풀이코드 C++

#include <bits/stdc++.h>
using namespace std;

int n, m, hx, hy, ex, ey, arr[1003][1003], vis[1003][1003][2];

int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

struct Edge {
	int x, y, op;
	Edge(int a, int b, int c) {
		x = a;
		y = b;
		op = c;
	}
};

void print() {
	for (int k = 1; k >= 0; k--) {
		if (k == 1) {
			cout << "벽 뚫기 전 \n";
		}
		else {
			cout << "벽 뚫은 후 \n";
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				cout << vis[i][j][k] << ' ';
			}
			cout << '\n';
		}
	}
	cout << "\n";
}



int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	queue<Edge> Q;
	cin >> n >> m;
	cin >> hx >> hy;
	cin >> ex >> ey;
	
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> arr[i][j];
		}
	}
	vis[hx][hy][1] = 1;
	Q.push(Edge(hx, hy, 1));

	while (!Q.empty()) {
		int x = Q.front().x;
		int y = Q.front().y;
		int op = Q.front().op;
		Q.pop();

		/*print();*/

		if (x == ex && y == ey) {
			if (vis[x][y][1] == 0) {
				cout << vis[x][y][0]- 1;
			}
			else cout << vis[x][y][1] -1 ;
			return 0;
		}

		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];


			if (nx<=0 || nx>n || ny<=0 || ny>m) continue;

			// 벽 뚫을 수 있음
			if (op == 1) {
				if (arr[nx][ny] == 0 && vis[nx][ny][1]==0) {
					vis[nx][ny][1] = vis[x][y][1] + 1;
					//벽 방문 가능
					Q.push({ nx,ny,1 });
				}
				else if (arr[nx][ny] == 1) {
					vis[nx][ny][0] = vis[x][y][1] + 1;
					//이제 벽 방문 기회 없음 
					Q.push({ nx,ny,0 });
				}
			}
			else {//벽 뚫을 기회 없음 무조건 0으로만 다녀야함
				if (arr[nx][ny] == 0 && vis[nx][ny][0] == 0) {
					vis[nx][ny][0] = vis[x][y][0] + 1;
					Q.push({ nx,ny,0 });
				}
			}
		}



	}


	cout << -1;

	return 0;
}

백준 14923 미로탈출 문제

 

반응형
반응형

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

 

15653번: 구슬 탈출 4

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'

www.acmicpc.net

 

 

기존 구슬 탈출 문제 풀이 및 설명

https://dingcoding.tistory.com/86

 

백준 13459번 : 구슬 탈출 - BFS C++ 문제풀이코드

https://www.acmicpc.net/problem/13459 13459번: 구슬 탈출 첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의..

dingcoding.tistory.com

 

BFS 제한 조건만 조금 바꿔주면 동일한 문제다.

 

C++ 문제풀이 코드

#include <bits/stdc++.h>
using namespace std;

int n, m;
char arr[15][15];
bool ch[15][15][15][15], isend;
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

struct Ball {
	int rx, ry, bx, by, trial;
	Ball(int a, int b, int c, int d, int e) {
		rx = a;
		ry = b;
		bx = c;
		by = d;
		trial = e;
	}
};


void move(int &nrx, int &nry, int dx, int dy, int &cnt) {
	while (1) {
		if (arr[nrx][nry] == '#') {
			nrx -= dx;
			nry -= dy;
			cnt--;
			break;
		}
		if (arr[nrx][nry] == 'O') {
			break;
		}
		nrx += dx;
		nry + dy;
		cnt++;
	}
}



int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	int rx1, ry1, bx1, by1;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> arr[i][j];
			if (arr[i][j] == 'R') {
				rx1 = i;
				ry1 = j;
			}
			else if (arr[i][j] == 'B') {
				bx1 = i;
				by1 = j;
			}
		}
	}

	queue<Ball> Q;
	ch[rx1][ry1][bx1][by1] = 1;
	Q.push(Ball(rx1, ry1, bx1, by1, 0));


	while (!Q.empty()) {
		int rx = Q.front().rx;
		int ry = Q.front().ry;
		int bx = Q.front().bx;
		int by = Q.front().by;
		int trial = Q.front().trial;
		Q.pop();

		for (int i = 0; i < 4; i++) {
			// 다음 빨간공과 다음 파란공의 좌표, cnt는 이동 거리 
			int nrx = rx, nry = ry, rcnt = 0;
			int nbx = bx, nby = by, bcnt = 0;

			//공 기울이기 
			move(nrx, nry, dx[i], dy[i], rcnt);
			move(nbx, nby, dx[i], dy[i], bcnt);

			
			if (arr[nbx][nby] == 'O') continue;
			else if (arr[nrx][nry] == 'O') {
				cout << trial + 1;
				isend = true;
				return 0;
			}
			else {
				//기울였는데 공이 겹친 경우 더 멀리서 온 공을 덜 이동시켜야된다
				if (nrx == nbx && nry == nby) {
					if (rcnt > bcnt) {
						nrx -= dx[i];
						nry -= dy[i];
					}
					else {
						nbx -= dx[i];
						nby -= dy[i];
					}
				}

				if (ch[nrx][nry][nbx][nby] == 0) {
					ch[nrx][nry][nbx][nby] = 1;
					Q.push(Ball(nrx, nry, nbx, nby, trial + 1));
				}
			}
		}
	}

	if (!isend) {
		cout << -1;
	}


}
반응형

+ Recent posts