본문 바로가기
Algorithm/백트래킹

[백준] N과M(1)~(4)풀이 c++

by 젊은오리 2023. 3. 4.
728x90

1. N과M (1) 

문제 링크 : https://www.acmicpc.net/problem/15649

문제

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
* 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열

KEY

  • 1~N의 수에 대해서 방문하지 않은 노드를 백트래킹을 활용하여 탐색하는 문제이다.
  • 1~N까지의 수는 모두 증가순이므로 자동으로 사전 순으로 출력되게 된다.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int n, m;
vector<int> v;
bool visited[9];
void dfs(int cnt) {
    //종료조건
    if (cnt == m) {
        for (int i = 0; i < v.size(); i++)
            cout << v[i] << " ";
        cout << "\n";
        return;
    }
 
    for (int i = 1; i <= n; i++) {
        if (visited[i])
            continue;
        
        visited[i] = true;
        v.push_back(i);
 
        dfs(cnt + 1);
        visited[i] = false;
 
        v.pop_back();
    }
}
int main()
{
    cin >> n >> m;
    dfs(0);
}
cs

 

 

2. N과M (2) 

문제 링크 : https://www.acmicpc.net/problem/15650

문제

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
* 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
* 고른 수열은 오름차순이어야 한다.

KEY

  • N과M (1)문제에서 오름차순이 추가된 문제이다.
  • 재귀함수 DFS의 인자에 현재 자신의 번호를 받아 자신의 번호~N까지의 수를 재탐색하게 한다.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int n, m;
vector<int> v;
bool visited[9];
void dfs(int cnt, int num) {
    //종료조건
    if (cnt == m) {
        for (int i = 0; i < v.size(); i++)
            cout << v[i] << " ";
        cout << "\n";
        return;
    }
 
    for (int i = num; i <= n; i++) {
        if (visited[i])
            continue;
        
        visited[i] = true;
        v.push_back(i);
 
        dfs(cnt + 1, i + 1);
 
        visited[i] = false;
        v.pop_back();
    }
}
int main()
{
    cin >> n >> m;
    dfs(0,1);
}
cs

 

3. N과M (3) 

문제 링크 : https://www.acmicpc.net/problem/15651

문제

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
*1부터 N까지 자연수 중에서 M개를 고른 수열
*같은 수를 여러 번 골라도 된다.

KEY

  • N과M (1)문제에서 방문배열을 빼주면 같은 수를 여러번 고를 수 있다.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int n, m;
vector<int> v;
void dfs(int cnt) {
    //종료조건
    if (cnt == m) {
        for (int i = 0; i < v.size(); i++)
            cout << v[i] << " ";
        cout << "\n";
        return;
    }
 
    for (int i = 1; i <= n; i++) {
        v.push_back(i); 
        dfs(cnt + 1);
        v.pop_back(); 
    }
}
int main()
{
    cin >> n >> m;
    dfs(0);
}
cs

 

 

4. N과M (4) 

문제 링크 : https://www.acmicpc.net/problem/15652

문제

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
*1부터 N까지 자연수 중에서 M개를 고른 수열
*같은 수를 여러 번 골라도 된다.
*고른 수열은 비내림차순이어야 한다.
        (길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.)

KEY

  • N과M (3)문제에서 조건에 비내림차순이 추가되었으므로 DFS함수의 인자에 현재 자신의 번호를 받아 자신의 번호~N까지의 수를 재탐색하게 한다.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int n, m;
vector<int> v;
void dfs(int cnt, int num) {
    //종료조건
    if (cnt == m) {
        for (int i = 0; i < v.size(); i++)
            cout << v[i] << " ";
        cout << "\n";
        return;
    }
 
    for (int i = num; i <= n; i++) {
        v.push_back(i); 
        dfs(cnt + 1, i);
        v.pop_back(); 
    }
}
int main()
{
    cin >> n >> m;
    dfs(0,1);
}
cs
728x90

댓글