코테/백준 문제풀이

백준 21611 마법사 상어와 블리자드

밤밭황제 2022. 4. 29. 23:19

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

 

21611번: 마법사 상어와 블리자드

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그, 비바라기 마법을 할 수 있다. 오늘 새로 배운 마법은 블리자드이고, 크기가 N×N인 격자에서 연습하려고 한다. N은 항상 홀수이고, (

www.acmicpc.net

#include <iostream>
#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)

using namespace std;
int N, M;
int cnt[4] = { 0, };
int map_idx[50][50];
int shark;
//아래 오른 위 왼
int dy[4] = { 1, 0, -1, 0 };
int dx[4] = { 0, 1 , 0, -1 };

//dir : 위 아래 왼 오
int y[4] = { -1, 1, 0, 0 };
int x[4] = { 0, 0 ,-1, 1 };
void copy_arr(int src[], int dst[])
{
	for (int i = 0; i < N * N; i++)
	{
		dst[i] = src[i];
	}
}
void draw_map_idx()
{
	int layer = 1;
	int r = shark;
	int c = shark - 1;
	int n = 1;
	int d = 0;
	while (1)
	{
		if (n == N * N)
		{
			return;
		}
		map_idx[r][c] = n;
		r = r + dy[d];
		c = c + dx[d];
		n++;
		if (r == shark + layer && c == shark - layer) //아래로 가다가 벽으로 막힘 -> 오른
			d = 1;
		if (r == shark + layer && c == shark + layer) // 오른쪽으로 가다가 막힘 -> 위로
			d = 2;
		if (r == shark - layer && c == shark + layer) //위로 가다가 막힘 ->왼
			d = 3;
		if (r == shark - layer && c == shark - layer)
		{
			map_idx[r][c] = n;
			n++;
			layer++;
			d = 0;
			c = shark - layer;
		}

	}
}
void bomb(int tarr[])
{

	for (int i = 1; i < N * N; i++)
	{
		int start = tarr[i];
		int con = 1;

		for (int j = i+1; j < N * N; j++)
		{
			int end = tarr[j];
			if (end == start)
			{
				con++;				
			}
			else
			{
				if (con >= 4)
				{
					cnt[start] += con;
					for (int k = i; k < j; k++)
					{
						tarr[k] = 0;
					}
					i = j - 1;
				}
				break;
			}
		}
	}

}
void crash(int dir, int leng, int map_arr[])
{
	int nlen = 0;
	int ny;
	int nx;
	//dir : 위 아래 왼 오
	while (nlen < leng)
	{
		nlen++;
		ny = (y[dir] * nlen) + shark;
		nx = (x[dir] * nlen) + shark;
		
		map_arr[map_idx[ny][nx]] = 0;
	}
}
void fill_arr(int srcarr[], int dstarr[])
{
	int tidx = 0;
	for (int i = 0; i < N * N; i++)
	{
		while (srcarr[tidx] == 0)
		{
			if (tidx > N * N)
				return;
			tidx++;
		}
		dstarr[i] = srcarr[tidx++];
	}
}

int check(int arr[])
{

	for (int i = 0; i < N * N; i++)
	{
		int start = arr[i];
		int con = 0;
		for (int j = i; j < i + 5; j++)
		{
			int end = arr[j];
			if (end == start && start != 0)
				con++;
			else
			{
				if (con >= 4)
					return 1;
				break;
			}
		}
	}
	return 0;
}

void change_map(int arr[], int dstarr[])
{
	int dst_idx = 1;
	for (int i = 1; i < N * N; i++)
	{
		if (dst_idx == N * N)
			return;
		if (arr[i] == 0)
			break;
		int b = arr[i];
		int a = 1;
		for (int j = i + 1; j < N * N; j++)
		{
			if (b == arr[j])
			{
				a++;
			}
			else
			{
				i = j - 1;
				break;
			}
		}
		dstarr[dst_idx++] = a;
		dstarr[dst_idx++] = b;
	}
}
int main()
{
	scanf("%d %d", &N, &M);
	shark = N / 2;
	int map_arr[2500];
	memset(map_arr, 0, sizeof(map_arr));
	draw_map_idx();

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			int marble;
			scanf("%d", &marble);
			map_arr[map_idx[i][j]] = marble;
		}
	}
	map_arr[0] = -1;
	int narr[2500];
	int n2arr[2500];

	for (int i = 0; i < M; i++)
	{
		//dir : 위 아래 왼 오
		int dir, leng;
		scanf("%d %d", &dir, &leng);
		crash(dir - 1, leng, map_arr);		
		memset(narr, 0, sizeof(narr));

		fill_arr(map_arr, narr); //crash 후에 채움

		while (check(narr))
		{
			memset(n2arr, 0, sizeof(n2arr));
			bomb(narr);
			fill_arr(narr, n2arr);
			memcpy(narr, n2arr, sizeof(n2arr));
		
		}
		memset(n2arr, 0, sizeof(n2arr));
		n2arr[0] = -1;
		change_map(narr, n2arr);		
		memcpy(map_arr, n2arr, sizeof(n2arr));
	
	}

	printf("%d", cnt[1] + 2 * cnt[2] + 3 * cnt[3]);
}
728x90