알고리즘/알고리즘 문제풀이

21922번: 학부 연구생 민상

b1ackhand 2022. 2. 14. 14:34

2022.02.14

 

문제 출처:

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

 

문제 분석:

문제의 조건에 따라 구현해 내는 구현 문제인것 같다.

 

문제 해결:

에어컨을 기준으로 상하좌우로 바람을 보내 바람이 물건을 만났을때 그에 해당하는 방향으로

회전 시켜주는 것을 구현하는 문제

물건 1,2 같은경우는 튕겨나가서 반대방향으로 가는것은 어차피 겹치기때문에 구현하지 않아도 되고

에어컨을 만나는 경우에는 그 에어컨에서 바람이 나올것이기 때문에 정지 해줘도 된다.

 

핵심은 방문처리를 하는 부분에서 방향에 따라 다르게 3차원으로 칠해야 되는 것 같다.

 

내 소스코드:

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int INF = 987654321;

int arr[2002][2002];
int N, M;
vector<pii> aircon;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};
int check[2002][2002][4];
int dirOp[4] = {2, 3, 0, 1};

int converter(int cur, int dir)
{
	if (cur == 3)
	{
		if (dir == 0)
			return 1;
		else if (dir == 1)
			return 0;
		else if (dir == 2)
			return 3;
		else if (dir == 3)
			return 2;
	}
	else if (cur == 4)
	{
		if (dir == 0)
			return 3;
		else if (dir == 1)
			return 2;
		else if (dir == 2)
			return 1;
		else if (dir == 3)
			return 0;
	}
	return 0;
}

void bfs(int startY, int startX)
{
	for (int i = 0; i < 4; i++)
	{
		check[startY][startX][i] = 1;
	}
	queue<pair<pii, int>> q;
	for (int i = 0; i < 4; i++)
	{
		q.push({{startY, startX}, i});
	}

	while (!q.empty())
	{
		int startY = q.front().F.F;
		int startX = q.front().F.S;
		int dir = q.front().S;
		q.pop();

		int nY = startY + dy[dir];
		int nX = startX + dx[dir];

		if (nY < 0 || nX < 0 || nY >= N || nX >= M)
			continue;
		if (check[nY][nX][dir] == 1)
			continue;

		check[nY][nX][dir] = 1;

		if (arr[nY][nX] == 0)
			q.push({{nY, nX}, dir});
		else if (arr[nY][nX] == 1 || arr[nY][nX] == 2)
		{
			if (arr[nY][nX] == 1)
			{
				if (dir == 1 || dir == 3)
				{
					check[nY][nX][dir] = 1;
					continue;
				}
				else
					q.push({{nY, nX}, dir});
			}
			else if (arr[nY][nX] == 2)
			{
				if (dir == 0 || dir == 2)
				{
					check[nY][nX][dir] = 1;
					continue;
				}
				else
					q.push({{nY, nX}, dir});
			}
		}
		else
		{
			q.push({{nY, nX}, converter(arr[nY][nX], dir)});
		}
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	memset(check, 0, sizeof(check));

	cin >> N >> M;

	rep(i, N)
	{
		rep(j, M)
		{
			cin >> arr[i][j];
			if (arr[i][j] == 9)
			{
				aircon.push_back({i, j});
			}
		}
	}

	for (int i = 0; i < aircon.size(); i++)
	{
		int airconY = aircon[i].F;
		int airconX = aircon[i].S;

		bfs(airconY, airconX);
	}

	int ans = 0;
	rep(i, N)
	{
		rep(j, M)
		{
			rep(k, 4)
			{
				if (check[i][j][k] == 1)
				{
					ans++;
					k = 4;
				}
			}
		}
	}

	cout << ans;

	return 0;
}

고찰: 

처음에 DFS로 짰을때 시간초과가 계속 났는데 원인을 알 수가 없어서

BFS로 고쳤더니 통과가 되었다.

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

Codeforces Round #790 (Div. 4) - B  (0) 2022.05.15
Codeforces Round #790 (Div. 4) - A  (0) 2022.05.15
1063번: 킹  (0) 2022.02.05
10164번: 격자상의 경로  (0) 2022.02.03
2539번: 모자이크  (0) 2022.01.24