[백트랙킹]로또

업데이트:

백준6603

_2021-02-04__3 25 44

_2021-02-04__3 26 11

주어진 수의 집합으로 가능한 모든 6자리 조합을 출력하면 된다. 문제를 해결하기 위해 백트랙킹을 사용할 때는, 두 가지 방법이 있다.

첫 번째는 문제에서 중복되는 조합 (i,j) ↔ (j,i) 를 허용하는지의 여부이다.

만약 문제에서 중복되는 조합을 허용한다면,

void func(int n){
	if(n==@){
		cout 
		return
	}
	for(int i=0;i<$;i++){
		func(n+1)
	}
}

의 형태를 따르면 된다. 기저 조건이 아닐 때 동작하는 반복문이 0에서 시작하는 것을 잘 확인해보면 된다.

만약 문제에서 중복되는 조합을 허용하지 않는다면, 즉 현재 문제처럼 1 2 3 4 5 6 7 과 7 6 5 4 3 2 1 이 같은 조합으로 취급되거나 오름차순, 내림차순 등의 출력을 요구한다면,

void func(int n,int start){
	if(n==@){
		cout 
		return
	}
	for(int i=start;i<$;i++){
		func(n+1,i+1)
	}
}

의 형태를 따르면 된다. 기저 조건이 아닐 때 동작하는 반복문이 직전에 호출한 인덱스부터 시작하는 것을 볼 수 있다.

첫 번째 방법을 사용하면 1 2 3 과 3 2 1 은 다른 조합으로 취급된다.

두 번째 방법을 사용하면 1 2 3 과 3 2 1 은 같은 조합으로 취급된다.

상황에 따라 맞는 방법을 택하면 된다.

현재 문제에서는 번호를 고르는 경우의 수를 요구하고 있기 때문에 두 번째 방법을 사용하면 된다.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int K;
vector<int> num;
int arr[6];
bool isUsed[50];

void init(){
    fill(isUsed,isUsed+50,false);
    num.clear();
}

void btk(int n, int start){
    if(n==6){
        for(int i=0;i<6;i++){
            cout << arr[i] << " ";  
        }
        cout << "\n";
        return;
    }
    for(int i=start;i<K;i++){
        if(!isUsed[num[i]]){
            arr[n] = num[i];
            isUsed[num[i]] = true;
            btk(n+1,i+1);
            isUsed[num[i]] = false;
        }
    }
}

int main(){
    
    while(1){
        cin >> K;
        if(K==0){
            return 0;
        }
        else{
            for(int i=0;i<K;i++){
                int temp; 
                cin >> temp;
                num.push_back(temp);
            }
        }
        btk(0,0);
        cout << endl;
        init();
        
    }
}

카테고리:

업데이트:

댓글남기기