[Baekjoon] - 13단계 : 백트래킹
1. N과 M
#include <stdio.h>
#include <stdbool.h>
int arr[9] = {0,};
bool visited[9] = {false,};
int n,m;
void dfs(int count){
if(count == m){
for(int i=0;i<m;i++){
printf("%d ",arr[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;i++){
if(!visited[i]){
visited[i] = true;
arr[count] = i;
dfs(count+1);
visited[i] = false;
}
}
}
int main(){
scanf("%d %d",&n, &m);
dfs(0);
}
2. N과 M (2)
#include <stdio.h>
#include <stdbool.h>
int arr[9] = {0,};
bool visited[9] = {false,};
int n,m;
bool check = false;//false이면 오름차순
void dfs(int count){
if(check) {//추가
check = false;
return;
}
if(count == m){
for(int i=0;i<m;i++){
printf("%d ",arr[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;i++){
if(!visited[i]){
visited[i] = true;
arr[count] = i;
if(count != 0){//추가
if(arr[count-1] > arr[count]){
check = true;
}
}
dfs(count+1);
visited[i] = false;
}
}
}
int main(){
scanf("%d %d",&n, &m);
dfs(0);
}
3. N과 M (3)
#include <stdio.h>
#include <stdbool.h>
int arr[9] = {0,};
int n,m;
void dfs(int count){
if(count == m){
for(int i=0;i<m;i++){
printf("%d ",arr[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;i++){
arr[count] = i;
dfs(count+1);
}
}
int main(){
scanf("%d %d",&n, &m);
dfs(0);
}
4. N과 M (4)
#include <stdio.h>
#include <stdbool.h>
int arr[9] = {0,};
int n,m;
bool check = false;//false이면 오름차순
void dfs(int count){
if(check) {//추가
check = false;
return;
}
if(count == m){
for(int i=0;i<m;i++){
printf("%d ",arr[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;i++){
arr[count] = i;
if(count != 0){//추가
if(arr[count-1] > arr[count]){
check = true;
}
}
dfs(count+1);
}
}
int main(){
scanf("%d %d",&n, &m);
dfs(0);
}
6. 스도쿠
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int board[10][10] = {0,};
bool possible(int row, int col, int num){//행,렬,3x3에서 공통적으로 남는수 여부
for(int i=0;i<9;i++){// 행, 렬
if(board[row][i] == num || board[i][col] == num)
return false;
}
int row33 = (row / 3) * 3;
int col33 = (col / 3) * 3;
for(int i=row33;i<row33+3;i++){// 3x3
for(int j=col33;j<col33+3;j++)
if(board[i][j] == num)
return false;
}
return true;
}
void sudoku(int row, int col){
if(col == 9){
sudoku(row+1, 0);
return;
}
if(row == 9){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
printf("%d ", board[i][j]);
}
printf("\n");
}
exit(0);//return 쓰면 틀림
}
if(board[row][col] == 0){
for(int i=1;i<=9;i++){
if(possible(row, col, i)){
board[row][col] = i;
sudoku(row, col+1);
}
}
board[row][col] = 0;//
return;
}
sudoku(row, col+1);
}
int main(){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++)
scanf("%d",&board[i][j]);
}
sudoku(0, 0);
}
7. 연산자 끼워넣기
#include <stdio.h>
int n;
int list[12] = {0,};
int min = 2100000000;
int max = -2100000000;
void dfs(int count, int value, int plus, int minus, int mul, int div){
if(count == n){
if(max < value) max = value;
if(min > value) min = value;
return;
}
else{
if(plus > 0) dfs(count+1, value+list[count], plus-1, minus, mul, div);
if(minus > 0) dfs(count+1, value-list[count], plus, minus-1, mul, div);
if(mul > 0) dfs(count+1, value*list[count], plus, minus, mul-1, div);
if(div > 0) dfs(count+1, value/list[count], plus, minus, mul, div-1);
}
}
int main(){
scanf("%d", &n);
for(int i=0;i<n;i++) scanf("%d",&list[i]);
int oper[5] = {0,};
for(int i=0;i<4;i++) scanf("%d",&oper[i]);
dfs(1, list[0], oper[0], oper[1], oper[2], oper[3]);
printf("%d\n%d",max ,min);
}
요약
- 1번을 기준으로
- 2번은 오름차순 비교만 추가해주면된다.(주석)
- 3번은 방문여부조건을 지워주면된다.
- 4번은 방문조건 지우고 오름차순비교 추가한다.