1317:【例5.2】组合的输出
【题目描述】
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你用递归的方法输出所有组合。
例如n=5,r=3,所有组合为:
1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
【题目分析】
1.搜索函数参数:上一次搜索的数字i(i(n)>=i(n-1)),要搜索的数位cnt
2.结束的条件:满足个数的要求cnt==k+1
3.枚举与回溯方式:
for (int i = b; i <= n; i++) {
if (vis[i] == 0) {
vis[i] = 1;
dfs(i + 1, r - 1);
vis[i] = 0;
}
}
【代码实现】
#include
using namespace std;
bool vis[21];
int n;
void dfs(int b, int r) { //r 控制循环层数 b控制循环起点
if (r == 0) {
for (int i = 1; i <= n; i++)
if (vis[i]) cout << " " << i ;
cout << endl;
return ;
};
for (int i = b; i <= n; i++) {
if (vis[i] == 0) {
vis[i] = 1;
dfs(i + 1, r - 1);
vis[i] = 0;
}
}
}
int main() {
//input data
int r;
cin >> n >> r;
dfs(1, r);
return 0;
}
1318:【例5.3】自然数的拆分
【题目描述】
任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。
当n=7共14种拆分方法:
【题目分析】
7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
.....
7=3+4
共14个
1.搜索函数参数:上一次搜索的数字i(i(n)>=i(n-1)),要搜索的数位cnt
2.结束的条件:和sum==n满足条件输出,sum>n不满足条件直接返回
3.枚举与回溯方式:
for (int i = m; i <= n; i++) {
a[index]=i;
sum+=i;
dfs(i,index+i);
sum-=i
}
【代码实现】
#include
using namespace std;
int n;
int a[100005];
int sum = 0;
void dfs(int m, int index) {
if (sum > n) return;
if (sum == n) {
cout << n << "=";
cout << a[1];
for (int i = 2; i < index; i++) {
cout << "+" << a[i];
}
cout << endl;
return;
}
for (int i = m; i < n; i++) {
a[index] = i;
sum += i;
dfs(i, index + 1);
sum -= i;
}
}
int main() {
//input data
cin >> n;
dfs(1, 1);
return 0;
}
1212:LETTERS
【题目描述】
给出一个roe×col的大写字母矩阵,一开始的位置为左上角,你可以向上下左右四个方向移动,并且不能移向曾经经过的字母。问最多可以经过几个字母。
【题目分析】
【代码实现】
#include
using namespace std;
int n, m;
char a[25][25];
bool vis[30];
int maxc = 0;
int _next[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void dfs(int i, int j, int cnt) {
maxc = max(cnt, maxc);
for (int k = 0; k <= 3; k++) {
int x = i + _next[k][0];
int y = j + _next[k][1];
if (x < 0 || y < 0 || x >= n || y >= m) continue;
if (vis[a[x][y] - 'A']) continue;
vis[a[x][y] - 'A'] = 1;
dfs(x, y, cnt + 1);
vis[a[x][y] - 'A'] = 0;
}
}
int main() {
//input data
cin >> n >> m;
getchar();
for (int i = 0; i < n; i++) {
cin.getline(a[i], 25);
}
vis[a[0][0] - 'A'] = 1;
maxc++;
dfs(0, 0, 1);
cout << maxc;
return 0;
}
1213:八皇后问题
【题目描述】
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
【题目分析】
【代码实现】
#inc