从 1~n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式
输入一个整数n。
输出格式
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好1个空格隔开。
对于没有选任何数的方案,输出空行。
本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
数据范围
1≤n≤151≤n≤15
输入样例:
3
输出样例:
3
2
2 3
1
1 3
1 2
1 2 3
题意是这样的,首先看一眼题目,知道这题必然是搜索也就是递归,那么怎么做呢,首先我们最重要的要一定要确定好搜索的状态,一个状态是当前最大的数m,另一个状态是当前搜索了几个数字,最后一个状态是需要搜索几个数字。
假如只搜索一个数字的话,我们的递归函数可以这样写。
int dfs(int m,int now,1)
{
}
接下来,我们需要确定好边界条件。
int dfs(int m,int now,1)
{
if(now==1)//边界条件
{
for(int i=1;i<=n;i++)//n是总共多少个数
{
if(visit[i])//遍历标记数组,找到已经存在的数字
{
cout<<i<<" ";
}
}
cout<<endl;
return 1;
}
}
接下来我们需要写递归函数
int dfs(int m,int now,1)
{
if(now==1)//边界条件
{
for(int i=1;i<=n;i++)
{
if(visit[i])
{
cout<<i<<" ";
}
}
cout<<endl;
return 1;
}
for(int i=m+1;i<=n;i++)//要注意m是这一层最大的数,不然的话很出现很多重复不需要的数字
{
if(!visit[i])
{
visit[i]=1;
dfs(i,now+1,goal);//往下回溯
visit[i]=0;
// dfs(i,now,goal);
// return 1;
}
}
}
就这样,搜索一个数的递归函数就写完了。很多地方我没细说,看上一篇递归题里面比较详细。
那么搜索n个数的递归函数其实就是在主函数里写个for循环。
下面是程序的全部代码:
#include <iostream>
#include <cstring>
using namespace std;
const int M=1000;
int n;
int visit[M];
int dfs(int m,int now,int goal)
{
if(now==goal)
{
for(int i=1;i<=n;i++)
{
if(visit[i])
{
cout<<i<<" ";
}
}
cout<<endl;
return 1;
}
for(int i=1;i<=n;i++)
{
if(!visit[i])
{
visit[i]=1;
dfs(i,now+1,goal);
visit[i]=0;
// dfs(i,now,goal);
// return 1;
}
}
}
int main()
{
cin>>n;
cout<<endl;
for(int i=1;i<=n;i++)
{
memset(visit,0,sizeof(visit));
dfs(0,0,i);
}
return 0;
}
当然还有一种做法,不过不推荐。————————————可以不看————————————————————————
#include <iostream>
#include <algorithm>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int M=1000;
int a[M],a_copy[M],m,book[M],record[M][M],k;
bool isre(int *a,int num)
{
int ok=1;
for(int i=0; i<=M; i++)
{
ok=1;
for(int j=1; j<=num; j++)
{
if(a[j]!=record[i][j])
{
ok=0;
}
}
if(ok)return true;
}
return false;
}
bool re(int *a,int num)
{
int ok=0;
for(int i=1;i<=num;i++)
{
ok=0;
for(int j=1;j<=num;j++)
{
if(a[i]==a[j])
{
ok++;
if(ok==2)return true;
}
}
}
return false;
}
void dfs(int n,int num)
{
if(n==m+1)
{
for(int i=1; i<=num; i++)a_copy[i]=a[i];
sort(a_copy+1,a_copy+num+1);
for(int j=1; j<=m; j++)
{
sort(a_copy+1,a_copy+m+1);
if(!isre(a_copy,j)&&!re(a_copy,j))
{
for(int i=1; i<=j; i++)
{
cout<<a_copy[i]<<" ";
}
for(int i=1; i<=j; i++)
{
record[k][i]=a_copy[i];
}
k++;
cout<<endl;
}
}
return;
}
for(int i=1; i<=m; i++)
{
if(!book[i])
{
book[i]=1;
a[i]=n;
dfs(n+1,i);
book[i]=0;
}
}
}
int main()
{
while(cin>>m)
{
dfs(1,1);
memset(a,0,sizeof(int)*M);
memset(book,0,sizeof(int)*M);
memset(a_copy,0,sizeof(int)*M);
memset(record,0,sizeof(int)*M*M);
}
return 0;
}