华师一附中OI组
标题:
P1157 组合的输出
[打印本页]
作者:
admin
时间:
2018-5-10 12:04
标题:
P1157 组合的输出
题目描述
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r<=n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你不用递归的方法输出所有组合。
例如n=5,r=3,所有组合为:
l 2 3 l 2 4 1 2 5 l 3 4 l 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
输入输出格式
输入格式:
一行两个自然数n、r(1<n<21,1<=r<=n)。
输出格式:
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
**注意哦!输出时,每个数字需要3个场宽,pascal可以这样:
write(ans:3);
输入输出样例
输入样例#1:
5 3
输出样例#1:
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
作者:
张笑宇
时间:
2018-5-13 17:28
#include<iostream>
#include<iomanip>
using namespace std;
const int nn=25,rr=25;
int a[nn];
int n,r;
void pp()
{
int i;
for (i=0;i<=r-1;i++) cout<<setw(3)<<a[i]+1;
cout<<endl;
}
void dfs(int i)
{
int k,p;
if (i>=r) pp();
else for (k=(i==0?0:a[i-1]+1);k<=n-1;k++)
{
a[i]=k;
dfs(i+1);
}
}
int main()
{
cin>>n>>r;
dfs(0);
return 0;
}
复制代码
作者:
黄煦喆
时间:
2018-5-13 20:28
#include<iostream>
#include<iomanip>
using namespace std;
int n,m,a[25];
void cmn(int i)
{
if(i>n){for(int j=1;j<=n;j++)cout<<setw(3)<<a[j];cout<<endl;}
else for(int k=a[i-1]+1;k<=m;k++)
{
a[i]=k;
cmn(i+1);
}
}
int main()
{
cin>>m>>n;
cmn(1);
return 0;
}
复制代码
作者:
walk_alone
时间:
2018-5-13 21:43
#include <cstdio>
int a[21],n,r,book[21];
void dfs(int step)
{
if(step==r+1)
{
for(int i=1;i<=r;i++)
printf("%3d",a[i]);
printf("\n");
}
else
for(int i=a[step-1]+1;i<=n;i++)
if(book[i]==0)
{
a[step]=i;
book[i]=1;
dfs(step+1);
book[i]=0;
a[step]=0;
}
}
int main()
{
scanf("%d%d",&n,&r);
dfs(1);
return 0;
}
复制代码
digger点评: 这位同学 你没有必要布尔数组 book[],因为组合,可以约定后面的数字比前面的大,那么就绝对不会重复。省掉一个变量,代码也简单多了。
作者:
wzd(temp)
时间:
2018-5-13 22:05
说好的不用递归呢。。。。
作者:
吴语林
时间:
2018-5-13 22:08
emmmmm,不用递归吗
作者:
admin
时间:
2018-5-13 23:05
说了 不准用递归的呢?
作者:
lyc
时间:
2018-5-16 13:34
模拟递归
#include<iostream>
#include<algorithm>
#include<vector>
#include<iomanip>
const int maxn = 100010;
using namespace std;
int stackn[maxn];
int top, address;
int n,m;
vector<int> choose;
void call(int x, int retadd){
int last = top;
stackn[++top] = x;///现在的
stackn[++top] = retadd;///返回地址
stackn[++top] = last;///上一个的栈顶
}
int ret(){
int retadd = stackn[top - 1];///返回地址
top = stackn[top];///还原到上一个栈顶
return retadd;
}
int main(){
cin>>n>>m;
call(1, 0);///开始
while(top){
int x = stackn[top-2];///现选的数
if(!address){///限制边界条件
if(choose.size()>m ||choose.size()+(n-x+1)<m){
address = ret();
continue;
}
if(x == n+1){
for(int i=0; i<choose.size(); i++)
cout<<setw(3)<<choose[i];
cout<<endl;
address = ret();
continue;
}
call(x+1, 1);///选下一个
address = 0;
continue;
}
if(address == 1){
choose.push_back(x);
call(x+1, 2);
address = 0;
continue;
}
if(address == 2){
choose.pop_back();///回溯
address = ret();
}
}
return 0;
}
复制代码
没必要这么复杂,你理解透彻之后再重做一下。
作者:
WWX
时间:
2018-5-16 16:30
#include<iostream>
#include<cstdio>
using namespace std;
int a[25];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=m;i++)
a[i]=i;
while(a[0]==0)
{
for(int i=1;i<=m;i++)
printf ("%3d",a[i]);
printf("\n");
int j=m;
while(a[j]==n-m+j)j--;
a[j]++;
for(int i=j+1;i<=m;i++)
a[i]=a[i-1]+1;
}
return 0;
}
作者:
YTC
时间:
2018-5-17 10:37
#include<iostream>
#include<iomanip>
using namespace std;
int a[101],n,m,top;
int main()
{
cin>>n>>m;
top=1;
while(top)
{
if(top>=m+1) {for(int i=1;i<=m;i++)cout<<setw(3)<<a[i];cout<<endl;top--;continue;}
if(a[top]==0) {a[top]=a[top-1]+1;top++;continue;}
if(a[top]+m-top<n) {a[top]++;top++;continue;}
a[top]=0;top--;
}
return 0;
}
复制代码
作者:
admin
时间:
2018-5-17 10:41
对!YTC好样的 就是要这样的一个程序!!!
作者:
liubo
时间:
2018-5-17 23:18
#include<iostream>
#include<iomanip>
using namespace std;
int a[1005],n,m,arr = 1;
int main()
{
cin >> n >> m;
while(arr){
if(arr >= m + 1){
for(int i = 1;i <= m;i++)
cout << setw(3) << a[i];
cout << endl;
arr--;
continue;
}
if(!a[arr]){
a[arr] = a[arr - 1] + 1;
arr ++;
continue;
}
if(a[arr] + m - arr < n){
a[arr++] ++;
continue;
}
a[arr--] = 0;
}
return 0;
}
复制代码
作者:
胡雨菲菲
时间:
2018-5-20 13:48
#include <cstdio>
#include <vector>
const int N = 100010;
int stak[N], top, p; /// 模拟系统栈
std::vector<int> v;
inline void call(int x, int add) {
int pre_top = top;
stak[++top] = x;
stak[++top] = add;
stak[++top] = pre_top;
p = 0;
return;
}
inline void ret() {
p = stak[top - 1];
top = stak[top];
return;
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
call(1, 0);
while(top) {
int x = stak[top - 2];
if(p == 0) {
if(v.size() == m) {
for(int i = 0; i < v.size(); i++) {
printf("%3d", v[i]);
}
printf("\n");
ret(); /// return;
continue;
}
if(x == n + 1 || v.size() + (n - x + 1) < m) {
ret(); /// return;
continue;
}
v.push_back(x);
call(x + 1, 1); /// DFS(x + 1);
continue;
}
else if(p == 1) {
v.pop_back();
call(x + 1, 2); /// DFS(x + 1);
continue;
}
else {
ret(); /// return;
continue;
}
}
return 0;
}
作者:
胡雨菲菲
时间:
2018-5-20 13:48
#include <cstdio>
#include <vector>
const int N = 100010;
int stak[N], top, p; /// 模拟系统栈
std::vector<int> v;
inline void call(int x, int add) {
int pre_top = top;
stak[++top] = x;
stak[++top] = add;
stak[++top] = pre_top;
p = 0;
return;
}
inline void ret() {
p = stak[top - 1];
top = stak[top];
return;
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
call(1, 0);
while(top) {
int x = stak[top - 2];
if(p == 0) {
if(v.size() == m) {
for(int i = 0; i < v.size(); i++) {
printf("%3d", v[i]);
}
printf("\n");
ret(); /// return;
continue;
}
if(x == n + 1 || v.size() + (n - x + 1) < m) {
ret(); /// return;
continue;
}
v.push_back(x);
call(x + 1, 1); /// DFS(x + 1);
continue;
}
else if(p == 1) {
v.pop_back();
call(x + 1, 2); /// DFS(x + 1);
continue;
}
else {
ret(); /// return;
continue;
}
}
return 0;
}
复制代码
作者:
Scorpio
时间:
2018-6-9 15:12
#include<iostream>
#include<iomanip>
using namespace std;
int a[105];
int m,n;
void hhh(int i)
{
int j,k;
if(i>=n+1)
{
for(j=1;j<=n;j++)
cout<<setw(3)<<a[j];
cout<<endl;
return;
}
else for(k=a[i-1]+1;k<=m;k++)
{
a[i]=k;
hhh(i+1);
}
}
int main()
{
cin>>m>>n;
hhh(1);
return 0;
}
复制代码
作者:
Duoluo
时间:
2018-6-16 16:40
#include <iostream>
using namespace std;
int n,r;
bool x[10];
int a[10];
void dfs(int i)
{
if(i==r)
{
for(int q=0;q<r;q++) cout<<a[q]<<" "; cout<<endl;
}
else
{
for(int j=1;j<=n;j++)
{
if(x[j])
{
a[i]=j;
if(i>0 && a[i-1]>a[i])
continue;
x[j]=false;
dfs(i+1);
x[j]=true;
}
}
}
}
int main()
{
cin>>n>>r;
for(int ans=1;ans<=n;ans++)
x[ans]=1;
dfs(0);
return 0;
}
作者:
吴语林
时间:
2018-6-25 19:31
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
int a[30],book[30],n,m;
void dfs(int cnt,int la)
{
if(cnt==m+1)
{
for(int i=1;i<=m;i++)
printf("%3d",a[i]);
printf("\n");
return;
}
for(int i=la+1;i<=n;i++)
if(!book[i])
{
book[i]=1,a[cnt]=i;
dfs(cnt+1,i);
book[i]=0;
}
}
int main()
{
scanf("%d%d",&n,&m);
dfs(1,0);
return 0;
}
复制代码
作者:
admin
时间:
2018-6-27 11:34
不要用dfs
作者:
朱品屹
时间:
2020-8-5 10:10
#include<bits/stdc++.h>
using namespace std;
int n,r;
int a[25];
bool b[25];
void pr()
{
for(int i=1;i<=r;i++) cout<<setw(3)<<a[i];
cout<<endl;
}
void dfs(int i)
{
if(i>r) pr();
else
{
for(int k=a[i-1]+1;k<=n;k++)
{
if(b[k]==1)
{
a[i]=k;
b[k]=0;
dfs(i+1);
b[k]=1;
}
}
}
}
int main()
{
cin>>n>>r;
for(int i=0;i<25;i++)
b[i]=1;
dfs(1);
return 0;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2