2 条题解

  • 0
    @ 2022-7-29 20:13:46
    stl大法好!
    #include<bits/stdc++.h>
    using namespace std;
    long x[35],n,r,i,s;
    int main()
    {
        cin>>n>>r;
        for(i=r+1;i<=n;i++)x[i]=1;
        do{
            for(i=1;i<=n;i++)if(!x[i])cout<<i;
            s++;
            cout<<' ';
        }while(next_permutation(x+1,x+n+1));
        cout<<endl<<s;
        return 0;
    }
    • 0
      @ 2022-7-5 11:03:23

      【问题描述】

      桐桐找出N个自然数(1,2,3,…,N)中的R个数的组合。例如,当n=5,r=3时,所有组合为123 124 125 134 135 145 234 235 245 345,总共有10种组合。

      思路

      很多人一看到题目就以为是全排列(包括我

      但是

      这里有一个坑,即每个数位上的数要大于之前那个数,如124,1<2<4,则这个数合法。 这样一来,一道DFS的气息暴露无遗。 代码奉上~~

      #include <bits/stdc++.h>
      using namespace std;
      #define ll long long
      inline ll read() {
      	char ch=getchar();
      	ll x=0,m=1;
      	while(!isdigit(ch)) {
      		if(ch=='-') m=-1;
      		ch=getchar();
      	}
      	while(isdigit(ch)) {
      		x = x * 10 + ch - 48;
      		ch=getchar();
      	}
      	return x*m;
      }
      inline void write(ll x) {
      	if(x<0) {
      		putchar('-');
      		write(-x);
      		return ;
      	}
      	if(x>=10) write(x/10);
      	putchar(x%10+'0');
      }//快读快输请不要在意
       
      ll n,r,ans;
      ll a[500000];
      inline void dfs(ll k,ll x) //k是当前搜到第几个数了,搜到r个数就停止;x是上次选的那个数,也是“每个数位上的数要大于之前那个数”条件的关键 
      {
      	if(k>r) //搜完了 
      	{
      		ans++;//方案数++ 
      		for(int i=1; i<=r; i++) write(a[i]);//输出这个数字 
      		putchar(' ');
      		return ;
      	}
      	for(int i=x+1; i<=n; i++)//从上一个选的数+1开始选 
      	{
      			a[k]=i;//选出当前数 
      			dfs(k+1,i);//前往下一层,当前选的数为i 
      	}
      	
      }
      signed main() //从主程序看是个好习惯 
      { 
      	n=read(),r=read();
      	dfs(1,0);//开始深搜之旅 
      	putchar('\n');
      	write(ans);//输出方案数 
      	return 0;
      }
      
      • 1

      信息

      ID
      66
      时间
      1000ms
      内存
      256MiB
      难度
      5
      标签
      (无)
      递交数
      93
      已通过
      38
      上传者