❶ 求高手解答本“实现数组全排列”的算法思想的详细思路。
如果排列因子数量很少, 可以用2进制位来表示。
如:["a", "b", "c", "d", "e"]可以按位表示
0 0 0 0 0
相应位为1时表示, 使用该因子。
❷ 求一个排列算法,或者解决的思路!若干矩形拼凑成一个矩形,不能重叠,如何排列可以使最终面积最小
1. 计算宽度之和、高度之和,如果宽度和较大则先处理2.1,否则先处理2.2
2.1. 按照宽度从小到大排列,宽度相同的矩形拼成更大的矩形
2.2. 按照高度做相同的处理
3. 重复以上步骤,直到没有宽、高相同的矩形
1. 计算宽度之和、高度之和,如果宽度和较大则先处理2.1,否则先处理2.2
2.1. 按照宽度从小到大排列,找出两个矩形,使得拼接后的“矩形”面积中空缺部分最小(较可能是宽度相差较小的两个矩形)。
2.2. 按照高度做相同的处理
3. 重复以上步骤,直到只剩下一个矩形(最终解)
以上两段其实是一个意思:尽量用较小的“面积损失”最大限度的减少待处理矩形数。只是第一段是特例,也就是无“面积损失”的拼接。
不过,一般来说,这不会是最优解。
❸ 用递归法进行n个数的全排列,思路是怎样的
比如有(1,2,3,4)这样一组数
1.先分成(1)和(2,3,4),然后对(2,3,4)全排列
2.把(1)分别和(2,3,4)中的数对调
3.比如一次调换(2),(1,3,4),然后对(2,3,4)全排列
4.调换的算完了,恢复,变成(1),(2,3,4),再调换下一个(3),(1,2,4)
大概就是这样的
--------------------------------
原来是填程序啊........
#include"stdio.h"
int a[10],n,count=0;
void perm(int k)
{
int p,t,j;
if( k==n )
{count++;
for(p=1;p<=k;p++) printf("%1d",a[p]);/*"%1d"中的数字是1,而不是字母l*/
printf(" ");
if( count%3==0 ) printf("\n");
return;}
for(j=k;j<=n;j++)
{t=a[k];a[k]=a[j];a[j]=t;
perm(k+1);
t=a[k];
a[k]=a[j];a[j]=t;}
}
main()
{int i;
printf("\nInput n:");
scanf("%d",&n);
for(i=1;i<=n;i++) a[i]=i;
perm(1);
}
❹ 数学排列问题
(1)4*4*3*2=96
(2)4*2*3*2=48
(3)(3+2+1)*2=12
12*3*2=72
(4)男生和女生相邻的排法有:3*2*2*2=24种
若不限制任何条件共有:5*4*3*2=120种排法
则男生和女生相间的排法有:120-24=96种
❺ 数学的排列组合算法加公式
不能重复的c(6,4) c(6,5) 1,2,3......,n n个数中 任取m个组合 c(n,m) 能重复的 6^4 6^5 1,2,3,。。。。n,n个数中,取m个组合(可重复) n^m 追问: c(n,m),读作什么?把1-6取4位带进去怎么算,可以教我吗?50分感激不尽 回答: 这个是组合数 从n个元素里面取m个元素的组合数 比如c(6,4)=(6*5*4*3)/(1*2*3*4) c(n,m)=[n*(n-1)*.........*(n-m+1)]/(1*2*......*m) 分子从n开始往下取 一直取m个连续的自然数相乘 分母从1取到m m个连续自然数相乘 追问: c(n,m)=[n*(n-1)*.........*(n-m+1)]/(1*2*......*m) 后面的/(1*2*......*m)是要除的么? 这个怎么求的? 回答: 你题目说的不是很清楚 如果说要是组成数字 就不需要除以下面的(排列) 若只是取出来 不要求构成数字 则要除(组合) 补充: 只算组合 不要求构成数字 你的做法是对的 补充: 不可重复 15组 可重复 6^4=1296组 补充: 估计你的题目是要求构成数字的 不可重复的就是 6*5*4*3=360种 可重复的还是1296种 补充: 你一直都没说 是否要求构成数字 取4个数字出来 是要构成一个4位数吗? 如果是 则是360种 不是 则是15种 补充: 这是你自己想的题目吧 原题绝对不会说这样的话 补充: 排列组合你没学 这些一下你也搞不懂的 打个比方,从1,2,3中取2个数字 则有3种取法 {1,2},{1,3),{2,3} 如果你要是说取2个数字构成2位数 则有6种12,21,13,31,23,32 你对照公式看下 追问: 就是6位取4位构成4位数就有360种,那么15种又是哪里来的? 回答: 晕了 我已经说的很清楚了啊 例子都列出来了 15种是取出来不进行排列 360是还要进去排列组成4位数 补充: 你要是自学排列组合 还是先把定义搞清楚吧 再说 你出的这个题目本身说的就模棱两可得 我一直在问你是否要求构成四位数 360和15得区别就在于这点 追问: 我终于懂了,在你们精心辅导下,我终于懂了,其实我对这些一窍不通,根本都没学!谢谢你们悬赏最高!
❻ 最短路线(排列组合)解题思路
画出题目所描述的网格,可以发现从西南到东北角最短要走10条短线,而且其中必有4条为竖线,从10条短线中选出4条作为路线中的竖线,也就确定了整条线路,所以一共有C10,4=210种路线(从10条线中选出6条横线一样)。
欢迎采纳,记得评价哦!
❼ 排列组合万能思路
1.2的倍数,末尾数字是偶数
(1)末尾数字是0,A(7,2)=42
(2)末尾数字是2,4,6 A(3,1)*A(6,1)*A(6,1)=108
2的倍数有150个
2.5的倍数,末尾数字是0,5
(1)末尾数字是0,A(7,2)=42
(2)末尾数字是5,A(6,2)*A(6,1)=36
5的倍数有42+36=78个
❽ JAVA中有哪几种常用的排序方法每个排序方法的实现思路是如何的每个方法的思想是什么
一、冒泡排序
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较 a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对 a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的。再对a[1]~a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。
优点:稳定;
缺点:慢,每次只能移动相邻两个数据。
二、选择排序
冒泡排序的改进版。
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序是不稳定的排序方法。
n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:
①初始状态:无序区为R[1..n],有序区为空。
②第1趟排序
在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
……
③第i趟排序
第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(1≤i≤n- 1)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。
优点:移动数据的次数已知(n-1次);
缺点:比较次数多。
三、插入排序
已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、 b[2]、……b[m],需将二者合并成一个升序数列。首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来 a[x]的位置这就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若无数组a,可将b[1]当作n=1的数组a)
优点:稳定,快;
缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。
三、缩小增量排序
由希尔在1959年提出,又称希尔排序(shell排序)。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、 a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以次类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。
优点:快,数据移动少;
缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。
四、快速排序
快速排序是目前已知的最快的排序方法。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先任取数据 a[x]作为基准。比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据<a[x],a[k+1]~a[n]中的每一个数据>a[x],然后采用分治的策略分别对a[1]~a[k-1]和a[k+1]~a[n] 两组数据进行快速排序。
优点:极快,数据移动少;
缺点:不稳定。
五、箱排序
已知一组无序正整数数据a[1]、a[2]、……a[n],需将其按升序排列。首先定义一个数组x[m],且m>=a[1]、a[2]、……a[n],接着循环n次,每次x[a]++.
优点:快,效率达到O(1)
缺点:数据范围必须为正整数并且比较小
六、归并排序
归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。最简单的归并是直接将两个有序的子表合并成一个有序的表。
归并排序是稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按输入的顺序.这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要.这也是它比快速排序优势的地方.
❾ C语言中全排列问题思路
方法1:如果位数不多穷举
方法2:位数多建议递归。
❿ 排序有几种方法
一. 冒泡排序
冒泡排序是是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把它们交换过来。遍历数列的工作是重复的进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端
1.冒泡排序算法的运作如下:
(1)比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个
(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素还是最大的数
(3)针对所有的元素重复以上的步骤,除了最后一个
二. 选择排序
选择排序是一种简单直观的排序算法。他的工作原理如下:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置(末尾位置),然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕
选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,他们当中至少有一个将被移到最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动 元素的排序方法中,选择排序属于非常好的一种
三. 插入排序
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在从后向前扫描的过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间
四. 快速排序
快速排序,又称划分交换排序。通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都要小,然后再按此方法对两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
五 希尔排序过程
希尔排序是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
六. 归并排序
归并排序是采用分治法(把复杂问题分解为相对简单的子问题,分别求解,最后通过组合起子问题的解的方式得到原问题的解)的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,水小九先取谁,取了后相应的指针就往后移一位。然后比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可