用双重解法理解排列“排列”
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;
}