inflearn logo
강의

Course

Instructor

Introduction to Algorithm Problem Solving for IT Employment (with C/C++): Coding Test Preparation

Programmers (Level 0-3) List of good problems to solve: 111 problems

풀어보면 좋은 문제 목록 - 2580 스토쿠 DFS 질문입니다!!

813

HB

12 asked

0

강의 완강하고 선생님께서 주신 추가 문제들 풀어보고 있습니다...

 

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

2580 스토쿠 문제같은 경우에 강의에서 배워왔던 dfs와 형태가 달라서 고생중입니다

 

 

#include <iostream>
#include <vector>
#include <map>

using namespace std;

int arr[82][82];

vector<pair<int, int> > v; //0위치

bool isRight(int n) { //조건 확인***
   .... (생략)
}

void dfs(int n) {
	if (n==(int)v.size()) {
		//결과 출력
		....(생략)
		exit(0);
		return;
	}
	else {
		//선택
		for (int i = 1; i <= 9; i++) {
			arr[v[n].first][v[n].second] = i; //값 넣기

			if (isRight(n)) { //백트래킹 조건 확인***
				dfs(n + 1); //계속 진행
			}
			//else { //취소***??????
			//	arr[v[n].first][v[n].second] = 0;
			//}		
		}

		arr[v[n].first][v[n].second] = 0;
	}
}

int main() {

	for (int i = 1; i <= 9; i++) {
		for (int j = 1; j <= 9; j++) {
			int tmp;
			cin >> tmp;
			if (tmp == 0) v.push_back(make_pair(i,j));
			arr[i][j] = tmp;
		}
	}

	dfs(0);

	return 0;
}

제 코드가 이러한데 (필요없는 부분은 생략했습니다)

dfs 재귀함수의 경우

v 벡터에 0인 곳의 좌표를 받고, dfs로 해당 좌표에 1부터 9까지 넣어보면서 선택하는 구조입니다.

근데...

재귀 전개하는 부분에서

arr[v[n].first][v[n].second] = 0;
	

주석에서도 나와있듯이 초기화 하는 부분이 for문 밖으로 빠져나와 있어야 정답으로 인정이 되더라구요

이해가 가지 않아서 질문을 드립니다

제 머리로는 위 부분이 for문 안쪽에 있는 것이랑

for문 바깥쪽에 있는것이랑 무슨 차이가 있는 것인지 전혀 모르겠습니다.

 


문제를 찾아낸 반례도 첨부합니다

for문 안쪽에 arr[v[n].first][v[n].second] = 0; 가 있을 시

이 케이스에서 0을 숫자로 하나도 채우지 못하고 그대로 결과가 나옵니다

for문 안쪽에 아래 구문이 있는 경우

arr[v[n].first][v[n].second] = 0;

왜 못 채우고 다 0으로 빠져나오는 건가요?

TEST CASE # 2

 

0 2 0 9 0 5 0 0 0

5 9 0 0 3 0 2 0 0

7 0 0 6 0 2 0 0 5

0 0 9 3 5 0 4 6 0

0 5 4 0 0 0 7 8 0

0 8 3 0 2 7 5 0 0

8 0 0 2 0 9 0 0 4

0 0 5 0 4 0 0 2 6

0 0 0 5 0 3 0 7 0

 

코테 준비 같이 해요! C++

Answer 2

1

codingcamp

안녕하세요^^

else 빼고 해보세요.

for (int i = 1; i <= 9; i++) {
			arr[v[n].first][v[n].second] = i; //값 넣기

			if (isRight(n)) { //백트래킹 조건 확인***
				dfs(n + 1); //계속 진행
			}
			
			arr[v[n].first][v[n].second] = 0;
					
		}

0

HB

원본 코드를 첨부합니다

#include <iostream>
#include <vector>
#include <map>

using namespace std;

int arr[82][82];

vector<pair<int, int> > v; //0위치

int d[] = {0,1,1,1,4,4,4,7,7,7}; //사각형

bool isRight(int n) { //조건 확인***
	int cnt = 0;
	int target = arr[v[n].first][v[n].second];
	
	//[1] 네모칸 하나 중복 확인
	int startr = d[v[n].first];
	int startc = d[v[n].second];

	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			if (target == arr[startr +i][startc +j]) cnt++;
			if (cnt == 2) return false;
		}
	}

	//[2] 가로 한줄 중복 확인	
	cnt = 0;
	for (int i = 1; i <= 9; i++) {
		if ( target == arr[v[n].first][i] ) cnt++;
		if (cnt == 2) return false;
	}	

	//[3] 세로 한줄 중복 확인	
	cnt = 0;
	for (int i = 1; i <= 9; i++) {
		if (target == arr[i][v[n].second]) cnt++;
		if (cnt == 2) return false;
	}

	return true;
}

void re(int n) {
	if (n==(int)v.size()) {
		//결과 출력
		for (int i = 1; i <= 9; i++) {
			for (int j = 1; j <= 9; j++) {
				cout << arr[i][j] << " ";
			}
			cout << endl;
		}
		exit(0);
		return;
	}
	else {
		//선택
		for (int i = 1; i <= 9; i++) {
			arr[v[n].first][v[n].second] = i; //값 넣기

			if (isRight(n)) { //백트래킹 조건 확인***
				re(n + 1); //계속 진행
			}
			//else { //취소***
			//	arr[v[n].first][v[n].second] = 0;
			//}		
		}

		arr[v[n].first][v[n].second] = 0;
	}
}

int main() {

	for (int i = 1; i <= 9; i++) {
		for (int j = 1; j <= 9; j++) {
			int tmp;
			cin >> tmp;
			if (tmp == 0) v.push_back(make_pair(i,j));
			arr[i][j] = tmp;
		}
	}

	re(0);

	//결과 출력
	for (int i = 1; i <= 9; i++) {
		for (int j = 1; j <= 9; j++) {
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}

	return 0;
}

테스트 케이스 질문

0

367

1

병합정렬 시간복잡도 질문

0

458

1

41.연속된 자연수의 합 문제풀이에서 수학적인 원리를 모르고 있습니다.

0

1339

2

질문드립니다.

0

371

1

질문드립니다!

0

425

1

dev 프로그램 질문

0

270

1

문제가 이해가 안되요

0

371

1

4번 나이차이 문제 접근법 질문 드립니다.

0

301

1

source file not compiled

0

1030

3

59번 질문드립니다.

0

366

1

25번 문제 질문

0

343

1

4. 나이차이 문제 질문입니다.

0

364

1

90번 라이언 킹 심바 1번 테스트 케이스

0

464

1

71번 문제 전역 변수 질문 있습니다

0

353

1

75번, 79번 priority_queue관련

1

351

1

75.최대 수입 스케줄

0

390

2

복면산 정답의 수

0

424

1

테스트 케이스에 대해서

0

438

1

수업 내용 질문입니다!

1

226

1

12. 플로이드-와샬(그래프 최단거리) . 27:25초

0

248

1

다른 풀이 방식

0

310

1

크루스칼 vs 프림

0

300

1

숫자 총개수 small 질문있습니다.

0

231

1

C/C++강의라고 하는데요

0

467

1