백준/탐색

[백준] C++ 1987(알파벳)

2zreal 2024. 7. 5. 21:20

 

#include <iostream>

using namespace std;

char arr[21][21];

void DFS(int i, int j, int count, int C[30]);

int result=0;
int row=0;
int col=0;


int main(void)
{
	cin>>row>>col;
	
	for(int i=0; i<row; i++)
	{
		for(int j=0; j<col; j++)
		{
			cin>>arr[i][j];
		}
	}
	int visited[30]={0};
	visited[(arr[0][0])-65]=1;
	DFS(0,0,0,visited);
	cout<<result+1;
	return 0;
}

void DFS(int i, int j, int count, int C[30])
{
	if(count>result)
	{
		result=count;
	}

	int temp1[30];
	int temp2[30];
	int temp3[30];
	int temp4[30];
	for(int k=0; k<=30; k++)
	{
		temp1[k]=C[k];
		temp2[k]=C[k];
		temp3[k]=C[k];
		temp4[k]=C[k];
	}
	
	if(C[int(arr[i+1][j])-65]==0&&i+1<row)
	{
		temp1[(arr[i+1][j])-65]=1;
		DFS(i+1,j,count+1,temp1);
	}
	if(C[int(arr[i-1][j])-65]==0&&i-1>-1)
	{
		temp2[(arr[i-1][j])-65]=1;
		DFS(i-1,j,count+1,temp2);
	}
	if(C[int(arr[i][j+1])-65]==0&&j+1<col)
	{
		temp3[(arr[i][j+1])-65]=1;
		DFS(i,j+1,count+1,temp3);
	}
	if(C[int(arr[i][j-1])-65]==0&&j-1>-1)
	{
		temp4[(arr[i][j-1])-65]=1;
		DFS(i,j-1,count+1,temp4);
	}
	
}

말은 상하좌우로 인접한 네 칸 중의 한 칸으로 이동할 수 있는데, 새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 한다.

즉 새로운 알파벳만 밟으면서 이동할 수 있는 거리의 최댓값을 찾는 문제이다.

 

N-퀸 문제를 해결해 봤으면 이 문제를 푸는 것은 어렵지 않을 것이다.

이 문제에서 주의할 점은 visited를 사용해야 한다는 것이다. 만약 이동한 순서대로 배열에 값을 저장하고 for문을 돌려 겹치는 알파벳이 있는지 확인하게 된다면 시간초과가 발생할 것이다.

이 문제에서 visited는 알파벳을 의미한다. (arr[i+1][j])-65 아스키코드를 이용해서 문제를 해결하면 된다.(예 A-65=0)

밟은 적이 없으면 이동이 가능하고 밟은 적이 있다면 이동이 불가능하다

 

이 문제를 해결하면서 알게 된 사실인데 

전역변수는 실행과 동시에 0값으로 초기화가 자동으로 되는데 지역변수는 자동으로 초기화가 되지 않는다. 만약 지역변수에 배열을 선언하게 된다면 명시적으로 초기화를 꼭 해주어야 한다.(지역변수는 보통 사용하기 전에 명시적으로 초기화를 하기 때문에 자동으로 초기화를 하게 되면 불필요한 오버헤드가 발생해서 자동으로 초기화하지 않는다고 한다.)

 

 

'백준 > 탐색' 카테고리의 다른 글

[백준] C++ 16236(아기 상어)  (1) 2024.07.10
[백준] C++ 1743(음식물 피하기)  (1) 2024.07.06
[백준] C++ 2589번(보물섬)  (0) 2024.07.04
[백준] C++ 2583(영역 구하기)  (0) 2024.07.04
[백준] C++ 2468(안전 영역)  (0) 2024.07.02