两种方法解决排列问题

用双重解法理解排列“排列”

Time Limit : 1.000 sec Memory Limit : 128 MB

Problem Description

有4个互不相同的数字,请按序输出由其中三个不重复数字组成的排列。

Input

4个整数。

Output

所有排列,输出顺序见样例。

Sample Input

1 2 3 4

Out Input

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
1 2 4
1 4 2
2 1 4
2 4 1
4 1 2
4 2 1
1 3 4
1 4 3
3 1 4
3 4 1
4 1 3
4 3 1
2 3 4
2 4 3
3 2 4
3 4 2
4 2 3
4 3 2

(一)基本函数求解法(不推荐)

类似于高中所用到的穷举法,将所有可能的结果全部罗列一般,比较浪费时间,而且fun函数中每个x,y,z顺序是固定的稍微改变一点就会导致编译错误,太过于死板
#include<stdio.h>
void fun(int x,int y,int z)
{
    printf("%d %d %d\n",x,y,z);
    printf("%d %d %d\n",x,z,y);
    printf("%d %d %d\n",y,z,x);
    printf("%d %d %d\n",y,x,z);
    printf("%d %d %d\n",z,x,y);
    printf("%d %d %d\n",z,y,x);
}

int main()

{
    int a,b,c,d;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    fun(a,b,c);
    fun(a,b,d);
    fun(a,c,d);
    fun(b,c,d);
    return 0;
}

(二)老药瓶——循环解法

不同于上面的函数穷举法,循环在这里的优势格外的突出,它不需要你再在源代码中将可能的组合一个个罗列出来,而是通过一个个循环嵌套的条件相互约束,将错误的数值去掉。
#include<stdio.h>
int main()
{
    int i,j,k,t,n,a[5];
    scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]);
    for(i=4; i>0; i--)
    {
        for(j=1; j<=4; j++)
            if(i!=j)
            {
                for(k=1; k<=4; k++)
                {
                    if(k!=i&&k!=j)
                    {
                        for(t=1; t<=4; t++)
                        {
                            if(t!=k&&t!=i&&t!=j)
                            {
                                printf("%d %d %d\n",a[j],a[k],a[t]);
                            }

                        }

                    }

                }

            }

    }

    return 0;
}

这个方法简单是简单,但是括号也太多了了吧,不自觉的让人感觉眼花缭乱,可不可以精简一些呢,答案是肯定的。本题属于循环中的个例,也许是物极必反吧(偷笑),其实这道题可以除了main函数的括号其他的一个也不用加,因为无论是for语句还是if语句,在不加括号的情况下只管下面的第一行代码,因此本题真正需要的括号只有一个。
#include<stdio.h>
int main()
{
    int i,j,k,t,n,a[5];
    scanf("%d%d%d%d",&a[1],&a[2],&a[3],&a[4]);
    for(i=4; i>0; i--)
    for(j=1; j<=4; j++)
    if(i!=j)
    for(k=1; k<=4; k++)
    if(k!=i&&k!=j)
    for(t=1; t<=4; t++)
    if(t!=k&&t!=i&&t!=j)
    printf("%d %d %d\n",a[j],a[k],a[t]);
    return 0;
}

个人建议不要将代码进行格式化,否则那种整齐的美感就没了(偷笑)。
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值