백준 1987번 (알파벳, C++, DFS) / 추가 반례 [BAEKJOON]

알파벳

www.acmicpc.net/problem/1987

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초256 MB81778262241605629.092%

문제

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다.
보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다.

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

좌측 상단에서 시작해서, 말이 최대한 몇 칸을 지날 수 있는지를 구하는 프로그램을 작성하시오.
말이 지나는 칸은 좌측 상단의 칸도 포함된다.

입력

첫째 줄에 R과 C가 빈칸을 사이에 두고 주어진다.
(1 ≤ R,C ≤ 20) 둘째 줄부터 R개의 줄에 걸쳐서 보드에 적혀 있는
C개의 대문자 알파벳들이 빈칸 없이 주어진다.

출력

첫째 줄에 말이 지날 수 있는 최대의 칸 수를 출력한다.

예제 입력 1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
2 4
CAAB
ADCB
2 4 CAAB ADCB
2 4
CAAB
ADCB

예제 출력 1

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
3
3
3

예제 입력 2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
3 6
HFDFFB
AJHGDH
DGAGEH
3 6 HFDFFB AJHGDH DGAGEH
3 6
HFDFFB
AJHGDH
DGAGEH

예제 출력 2

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
6
6
6

예제 입력 3

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
5 5
IEFCJ
FHFKC
FFALF
HFGCF
HMCHH
5 5 IEFCJ FHFKC FFALF HFGCF HMCHH
5 5
IEFCJ
FHFKC
FFALF
HFGCF
HMCHH

예제 출력 3

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
10
10
10

출처

Olympiad > Croatian Highschool Competitions in Informatics > 2002 > 
Regional Competition – Juniors 3번

알고리즘 분류


추가 반례

예제 입력 A

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
3 4
ABCD
BCDA
CDEF
3 4 ABCD BCDA CDEF
3 4

ABCD

BCDA

CDEF

예제 출력 3

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
3
3
3

예제 입력 B

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
10 10
ASWERHGCFH
QWERHDLKDG
ZKFOWOHKRK
SALTPWOKSS
BMDLKLKDKF
ALSKEMFLFQ
GMHMBPTIYU
DMNKJZKQLF
HKFKGLKEOL
OTOJKNKRMW
10 10 ASWERHGCFH QWERHDLKDG ZKFOWOHKRK SALTPWOKSS BMDLKLKDKF ALSKEMFLFQ GMHMBPTIYU DMNKJZKQLF HKFKGLKEOL OTOJKNKRMW
10 10
ASWERHGCFH
QWERHDLKDG
ZKFOWOHKRK
SALTPWOKSS
BMDLKLKDKF
ALSKEMFLFQ
GMHMBPTIYU
DMNKJZKQLF
HKFKGLKEOL
OTOJKNKRMW

예제 출력 B

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
22
22
22

예제 입력 C

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
20 20
POIUYTREWQBWKALSLDLG
LKJHGFDSAMASFBMBOSOZ
NMBVCXZAKPAISJLBMROW
CEVTBFNIMLASNCVKNDKX
VPQLBKENMSAHBBLFOWPQ
ZLSKJJBNBEASZNFDGHHN
GPBMDLQDALAASBBXCEGA
APQIKBMROIBANPOBLMKS
ASKSKVJRPORHNOXZKSPN
LSNVOEOOOKAKANLGKOAX
AKVMBOTOWPQOJBSMSPEP
BLLBKWPEPBKNMROSALLP
BNQLDNBMKOVMEMELSLMA
RLEPQQPVKJRNBITNBSAS
ZXMCOITRPWKLPGKHNGMS
QOBKRPPPZSLEMPNKSPPR
OQJDNZNANDWKQKVJEOGJ
QUYVOIUYWERLKJHASDFV
ZCVWRETPOIUHJKLVBMAS
QWERZCVUIAFDKHSDFHSA
20 20 POIUYTREWQBWKALSLDLG LKJHGFDSAMASFBMBOSOZ NMBVCXZAKPAISJLBMROW CEVTBFNIMLASNCVKNDKX VPQLBKENMSAHBBLFOWPQ ZLSKJJBNBEASZNFDGHHN GPBMDLQDALAASBBXCEGA APQIKBMROIBANPOBLMKS ASKSKVJRPORHNOXZKSPN LSNVOEOOOKAKANLGKOAX AKVMBOTOWPQOJBSMSPEP BLLBKWPEPBKNMROSALLP BNQLDNBMKOVMEMELSLMA RLEPQQPVKJRNBITNBSAS ZXMCOITRPWKLPGKHNGMS QOBKRPPPZSLEMPNKSPPR OQJDNZNANDWKQKVJEOGJ QUYVOIUYWERLKJHASDFV ZCVWRETPOIUHJKLVBMAS QWERZCVUIAFDKHSDFHSA
20 20
POIUYTREWQBWKALSLDLG
LKJHGFDSAMASFBMBOSOZ
NMBVCXZAKPAISJLBMROW
CEVTBFNIMLASNCVKNDKX
VPQLBKENMSAHBBLFOWPQ
ZLSKJJBNBEASZNFDGHHN
GPBMDLQDALAASBBXCEGA
APQIKBMROIBANPOBLMKS
ASKSKVJRPORHNOXZKSPN
LSNVOEOOOKAKANLGKOAX
AKVMBOTOWPQOJBSMSPEP
BLLBKWPEPBKNMROSALLP
BNQLDNBMKOVMEMELSLMA
RLEPQQPVKJRNBITNBSAS
ZXMCOITRPWKLPGKHNGMS
QOBKRPPPZSLEMPNKSPPR
OQJDNZNANDWKQKVJEOGJ
QUYVOIUYWERLKJHASDFV
ZCVWRETPOIUHJKLVBMAS
QWERZCVUIAFDKHSDFHSA

예제 출력 C

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
26
26
26

<틀린 코드>

오답이 나오는 반례는 없었으나… 계속되는 틀렸습니다…

포기하고 다르게 접근했다.

틀린 코드

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <iostream>
#include <queue>
#include <string>
#include <set>
using namespace std;
#define MAX 21
int row, column, result;
char map[MAX][MAX];
bool mapcheck[MAX][MAX] = {false};
set<string> mySet;
struct Pos {
// 나의 위치, 이동 횟수
int posX, posY, trace;
string strTrace;
} sPos;
// 나의 위치를 표현
queue<Pos> myQueue;
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
int main()
{
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
map[i][j] = 'x';
}
}
cin >> row >> column;
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= column; j++)
{
char temp = ' ';
cin >> temp;
map[i][j] = temp;
}
}
result = 0;
sPos.posX = 1;
sPos.posY = 1;
sPos.trace = 0;
sPos.strTrace = "";
myQueue.push(sPos);
while (!myQueue.empty())
{
Pos temp = myQueue.front();
myQueue.pop();
temp.strTrace.push_back(map[temp.posX][temp.posY]);
temp.trace += 1;
mapcheck[temp.posX][temp.posY] = true;
if (result < temp.trace) result = temp.trace;
if (mySet.count(temp.strTrace) != 0) continue;
for (int i = 0; i < 4; i++)
{
int nx = temp.posX + dx[i];
int ny = temp.posY + dy[i];
if (mapcheck[nx][ny]) continue;
if (nx <= 0 || nx > MAX || ny <= 0 || ny > MAX) continue;
if (map[nx][ny] == 'x') continue;
if (temp.strTrace.find(map[nx][ny]) != string::npos) continue;
mySet.insert(temp.strTrace);
Pos temp2 = temp;
temp2.posX = nx;
temp2.posY = ny;
//cout << temp2.strTrace << "\n";
myQueue.push(temp2);
}
}
cout << result;
return 0;
}
#include <iostream> #include <queue> #include <string> #include <set> using namespace std; #define MAX 21 int row, column, result; char map[MAX][MAX]; bool mapcheck[MAX][MAX] = {false}; set<string> mySet; struct Pos { // 나의 위치, 이동 횟수 int posX, posY, trace; string strTrace; } sPos; // 나의 위치를 표현 queue<Pos> myQueue; int dx[4] = { 0, 0, 1, -1 }; int dy[4] = { 1, -1, 0, 0 }; int main() { for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { map[i][j] = 'x'; } } cin >> row >> column; for (int i = 1; i <= row; i++) { for (int j = 1; j <= column; j++) { char temp = ' '; cin >> temp; map[i][j] = temp; } } result = 0; sPos.posX = 1; sPos.posY = 1; sPos.trace = 0; sPos.strTrace = ""; myQueue.push(sPos); while (!myQueue.empty()) { Pos temp = myQueue.front(); myQueue.pop(); temp.strTrace.push_back(map[temp.posX][temp.posY]); temp.trace += 1; mapcheck[temp.posX][temp.posY] = true; if (result < temp.trace) result = temp.trace; if (mySet.count(temp.strTrace) != 0) continue; for (int i = 0; i < 4; i++) { int nx = temp.posX + dx[i]; int ny = temp.posY + dy[i]; if (mapcheck[nx][ny]) continue; if (nx <= 0 || nx > MAX || ny <= 0 || ny > MAX) continue; if (map[nx][ny] == 'x') continue; if (temp.strTrace.find(map[nx][ny]) != string::npos) continue; mySet.insert(temp.strTrace); Pos temp2 = temp; temp2.posX = nx; temp2.posY = ny; //cout << temp2.strTrace << "\n"; myQueue.push(temp2); } } cout << result; return 0; }
#include <iostream>
#include <queue>
#include <string>
#include <set>

using namespace std;

#define MAX 21

int row, column, result;
char map[MAX][MAX];
bool mapcheck[MAX][MAX] = {false};
set<string> mySet;

struct Pos {
	// 나의 위치, 이동 횟수
	int posX, posY, trace;
	string strTrace;
} sPos;

// 나의 위치를 표현
queue<Pos> myQueue;

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

int main()
{
	for (int i = 0; i < MAX; i++)
	{
		for (int j = 0; j < MAX; j++)
		{
			map[i][j] = 'x';
		}
	}

	cin >> row >> column;
	for (int i = 1; i <= row; i++)
	{
		for (int j = 1; j <= column; j++)
		{
			char temp = ' ';
			cin >> temp;
			map[i][j] = temp;
		}
	}

	result = 0;
	sPos.posX = 1;
	sPos.posY = 1;
	sPos.trace = 0;
	sPos.strTrace = "";
	myQueue.push(sPos);

	while (!myQueue.empty())
	{
		Pos temp = myQueue.front();
		myQueue.pop();
		temp.strTrace.push_back(map[temp.posX][temp.posY]);
		temp.trace += 1;
		mapcheck[temp.posX][temp.posY] = true;
		
		if (result < temp.trace) result = temp.trace;
		if (mySet.count(temp.strTrace) != 0) continue;

		for (int i = 0; i < 4; i++)
		{
			int nx = temp.posX + dx[i];
			int ny = temp.posY + dy[i];

			if (mapcheck[nx][ny]) continue;
			if (nx <= 0 || nx > MAX || ny <= 0 || ny > MAX) continue;
			if (map[nx][ny] == 'x') continue;
			if (temp.strTrace.find(map[nx][ny]) != string::npos) continue;
			mySet.insert(temp.strTrace);

			Pos temp2 = temp;
			temp2.posX = nx;
			temp2.posY = ny;

			//cout << temp2.strTrace << "\n";
			myQueue.push(temp2);
		}
	}

	cout << result;
	return 0;
}

통과된 코드(DFS)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include <iostream>
using namespace std;
// 행, 열, 결과
int row, column, result;
// 알파벳 중복 방지
bool isVisited[26];
// 맵 표시
char mapArr[20][20];
// 상 하 좌 우
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
void DFS(int x, int y, int cnt) {
// 결과값 보다 높으면 값을 바꾸어 준다.
if (cnt > result)
{
result = cnt;
}
for (int i = 0;i < 4;i++)
{
// 상 하 좌 우 움직여주기
int nx = x + dx[i];
int ny = y + dy[i];
// 범위를 벗어나면 실행 X
if (nx >= 0 && ny >= 0 && nx < column && ny < row)
{
// A - 65 이번 배열에 A가 있다면 -65 = 0
// isVisited[0] 방문 처리
if (isVisited[mapArr[ny][nx] - 'A'] == false)
{
isVisited[mapArr[ny][nx] - 'A'] = true;
DFS(nx, ny, cnt + 1);
isVisited[mapArr[ny][nx] - 'A'] = false;
// DFS가 끝나면서 방문 처리 해제
}
}
}
}
int main()
{
cin >> row >> column;
for (int i = 0;i < row;i++)
{
for (int j = 0;j < column;j++)
{
cin >> mapArr[i][j];
}
}
// 첫시작
isVisited[mapArr[0][0] - 'A'] = true;
// DFS 시작
DFS(0, 0, 1);
cout << result;
return 0;
}
#include <iostream> using namespace std; // 행, 열, 결과 int row, column, result; // 알파벳 중복 방지 bool isVisited[26]; // 맵 표시 char mapArr[20][20]; // 상 하 좌 우 int dx[4] = { 0, 0, 1, -1 }; int dy[4] = { 1, -1, 0, 0 }; void DFS(int x, int y, int cnt) { // 결과값 보다 높으면 값을 바꾸어 준다. if (cnt > result) { result = cnt; } for (int i = 0;i < 4;i++) { // 상 하 좌 우 움직여주기 int nx = x + dx[i]; int ny = y + dy[i]; // 범위를 벗어나면 실행 X if (nx >= 0 && ny >= 0 && nx < column && ny < row) { // A - 65 이번 배열에 A가 있다면 -65 = 0 // isVisited[0] 방문 처리 if (isVisited[mapArr[ny][nx] - 'A'] == false) { isVisited[mapArr[ny][nx] - 'A'] = true; DFS(nx, ny, cnt + 1); isVisited[mapArr[ny][nx] - 'A'] = false; // DFS가 끝나면서 방문 처리 해제 } } } } int main() { cin >> row >> column; for (int i = 0;i < row;i++) { for (int j = 0;j < column;j++) { cin >> mapArr[i][j]; } } // 첫시작 isVisited[mapArr[0][0] - 'A'] = true; // DFS 시작 DFS(0, 0, 1); cout << result; return 0; }
#include <iostream>

using namespace std;

// 행, 열, 결과
int row, column, result;

// 알파벳 중복 방지
bool isVisited[26];

// 맵 표시
char mapArr[20][20];

// 상 하 좌 우
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };

void DFS(int x, int y, int cnt) {

    // 결과값 보다 높으면 값을 바꾸어 준다.
    if (cnt > result)
    {
        result = cnt;
    }

    for (int i = 0;i < 4;i++)
    {
        // 상 하 좌 우 움직여주기
        int nx = x + dx[i];
        int ny = y + dy[i];

        // 범위를 벗어나면 실행 X
        if (nx >= 0 && ny >= 0 && nx < column && ny < row)
        {
            // A - 65  이번 배열에 A가 있다면 -65 = 0
            // isVisited[0] 방문 처리
            if (isVisited[mapArr[ny][nx] - 'A'] == false)
            {
                isVisited[mapArr[ny][nx] - 'A'] = true;
                DFS(nx, ny, cnt + 1);
                isVisited[mapArr[ny][nx] - 'A'] = false;
                // DFS가 끝나면서 방문 처리 해제
            }
        }
    }
}

int main() 
{
    cin >> row >> column;

    for (int i = 0;i < row;i++) 
    {
        for (int j = 0;j < column;j++) 
        {
            cin >> mapArr[i][j];
        }
    }

    // 첫시작
    isVisited[mapArr[0][0] - 'A'] = true;

    // DFS 시작
    DFS(0, 0, 1);

    cout << result;

    return 0;
}

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다