12.29

本文介绍了两个编程问题的解决方案:一是通过深度优先搜索实现自然数的拆分,输出所有可能的加法序列;二是使用递归生成全排列,输出给定字符的所有排列组合。这两个算法都是经典的计算机科学问题,涉及到排列组合和搜索策略。
摘要由CSDN通过智能技术生成

P2404 自然数的拆分问题

题目描述

任何一个大于 11 的自然数 nn,总可以拆分成若干个小于 n 的自然数之和。现在给你一个自然数 n,要求你求出 n的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数 n

输出格式

输出:若干数的加法式子。

输入输出样例

输入

7

输出

1+1+1+1+1+1+1

1+1+1+1+1+2

1+1+1+1+3

1+1+1+2+2

1+1+1+4

1+1+2+3

1+1+5

1+2+2+2

1+2+4

1+3+3

1+6

2+2+3

2+5

3+4

#include<stdio.h>
#include<string.h>
#include<stdlib.h> 
int a[10];//记录答案 
void dfs(int s,int step)
{
    if(s==0)//终止条件 
    {
        for(int i=0;i<step-1;i++)
        printf("%d+",a[i]);
        printf("%d\n",a[step-1]);
    }
    for(int i=1;i<=s;i++)
    {
        if(i<a[step-1]) continue;//是否合法 
        a[step]=i;//合法就储存 
        dfs(s-i,step+1);//继续拆分 
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n/2;i++)
    {
        a[0]=i;
        dfs(n-i,1);
    }
    return 0;
}

问题 L: 全排列(JSU-ZJJ)(❤❤❤❤

题目描述

给定n个字符{r1,r2,…,rn},要求生成这n个字符的全排序。

生成全排列思想如下:

设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。

集合X中元素的全排列记为perm(X)。

(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。R的全排列可归纳定义如下:

当n=1时,perm(R)=(r),其中r是集合R中唯一的元素;

当n>1时,perm(R)由(r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn)构成。

输入

输入包括若干个用例,第一行为一个正整数k(1<=k<=10),表示用例个数。

每个用例占两行,其中第一行为该用例字符的个数n(1<=n<=5),第二行为n个字符,字符可以是数字和大小写字母,字符之间用空格隔开。

可以假定给定同一用例中不出现相同的字符。

输出

输出每个用例的全排列,每一个排列占一行。各用例全排序之间用一空行隔开。

样例输入
2
2
1 2
3
a c b
样例输出
12
21

acb
abc
cab
cba
bca
bac
#include<stdio.h>
#include<string.h>
#include<stdlib.h> 
int n;
char a[20];
int top = 0;
void swap(char*p,char*q)
{
    char t;
    t=*p;
    *p=*q;
    *q=t;
}
void dfs(int c)
{
    if (c == n)
    {
        for (int i = 0; i < n; i++)
            printf("%c", a[i]);
        printf("\n");
        return;
    }
    int i;
    for (i = c; i < n; i++)
    {
        swap(&a[c],&a[i]);
        dfs(c+1);
        swap(&a[i],&a[c]);
    }    
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        getchar();
        for (int i = 0; i < n; i++)
        {
            scanf("%c", &a[i]);
            getchar();
        }
        dfs(0);
        printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值