全排列(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中唯一的元素;
当n>1时,perm®由(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"
char a[6];
int n;
void swap(char *a,char *b)
{
    char t;
    t=*a;
    *a=*b;
    *b=t;
}
int dfs(int t)
{
    int i;
    if(t==n-1)
    {
        for(i=0; i<n-1; i++)
            printf("%c",a[i]);
        printf("%c\n",a[i]);
        return 0;
    }
    else
    {
        for(i=t; i<n; i++)//像回溯,却不是。
        {
            swap(&a[i],&a[t]);
            dfs(t+1);
            swap(&a[t],&a[i]);
        }
    }
}

int main()
{
    int k,i,j,t;
    char s;
    while(~scanf("%d",&k))
    {
        n=0;
        for(i=0; i<6; i++)
            a[i]='\0';
        while(k--)
        {

            scanf("%d",&n);
            {
                scanf("%c",&s);
                for(i=0; i<n; i++)
                {
                    scanf("%c%c",&a[i],&s);
                }
                /*   printf("a数组值\n");
                       for(i=0;i<n;i++)
                            printf("%c",a[i]);
                       printf("\n");*/
                dfs(0);
                printf("\n");
            }
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值