本人对解决算法有兴趣,曾在网上看到过一道阿里巴巴的面试题.

题目是这样的:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

所以自己也考虑了一个算法,也在网上看到别人的不同的算法。感觉我这个算法遍历效率很高,而且也很简洁(不敢用最来形容,怕强中更有强中手,当然如果能推导出公式来求解的话肯定会比我这个算法快,这个公式是F(n) = (n! / ((n/2)! * (n/2)!))/ (n/2 +1)).

我的算法思想是这样的:

(1)把排队的问题转换成数字排列问题,类似于0- 11这12个数排成2行。

(2)可以只考虑前一排的情况,因为只要前一排是符合某些条件,剩余的数按顺序放后排自然能满足条件。

(3)第一排数要符合的条件是:

下面数值表示的是位置,

0   1   2   3   4   5

6   7   8   9 10 11

对于位置0,可能的数的范围是0

对于位置1,可能的数的范围是1,2

对于位置2,可能的数的范围是2,3,4

对于位置3,可能的数的范围是3,4,5,6

对于位置4,可能的数的范围是4,5,6,7,8

对于位置5,可能的数的范围是5,6,7,8,9,10

这样可以推导出:

对于位置为n的数,其数的范围是[n, 2n].

这样对于0-5的位置的数的范围就是[{0,1,2,3,4,5}, {0,2,4,6,8,10}],

我们把这个0-5的位置的数当成一个大的数来看待,对其进行++操作,只不过进位的时候是按每个位置的数的范围来进行进位。

比如:

1.目前数是{0,1,2,3,4,5}, ++操作后,数变为{0,1,2,3,4,6},因为6小于且等于位置5的最大值2n = 10,所以此组合是个符合要求的组合。

2.又如目前数是{0,1,2,3,4,10}, ++操作后,数变为{0,1,2,3,4,11},因为11大于位置5的最大值2n = 10, 因此要进位,这样位置4的数++,再检查位置4的数++后是5,小于且等于位置4的最大值2n = 8,这个位置符合条件,而位置5的数要置"0",这个0不能是再从范围的起始值开始,而是要等于位置4的数+1.因为从起始值开始的数肯定是小于位置4的值的。

3.以此类推,如果目前数是{0,1,4,6,8,10},++操作后,需要进位,一步一步往前进位,最终进位位置1的数,数就变成了{0,2,5,7,9,11},然后要把位置1之后位置的每个位置的数置"0", 等于前一个位置的数+1,这样最后数就是{0,2,3,4,5,6}.

4.检查此数组合是否符合条件是,检查最后一个数是否小于且等于其位置的最大值。

附算法如下:

#include

#include

usingnamespace std;

classpai2dui

{

public:

pai2dui(int n)

:mMaxNum(n / 2)

,mCount(0)

,mAllCount(0)

{

if (n > 1)

{

mCount = 1;

for(int i = 0; i < n / 2; i++)

{

mData.push_back(i);

}

}

}

void run()

{

if(mMaxNum <= 0)

{

return;

}

int i = mMaxNum - 1;//从最后一个数开始++操作

while (i)

{

++mData[i];//对位置为i的数进行++操作

mAllCount++;//总循环的此数计数.

if (mData[i] <= 2 * i)

{//如果该位置的数不超过对应位置的最大值,那么对其后面的位置的数置”0”.

for (int j = i + 1; j < mMaxNum; j++)

{//其后面位置的数等前面位置的数+1,能确保这个数是进位后”最小”符合的数的组合

mData[j] = mData[j - 1] + 1;

}

}

else

{//如果该位置的数超过了对应位置的数的最大值,将数的位置往前移动一位,然后使用

// continue重新++操作。

i--;

continue;

}

if (mData[mMaxNum - 1] <= 2 * (mMaxNum - 1))

{//检查最后一位的数是否小于且等于其位置的最大值,如果是的话,此数组合符合要求

//计数并打印

++mCount;

for(int k = 0; k < mMaxNum; k++)

{

cout<< mData[k] << " ";

}

cout << endl;

//把++操作的数的位置置回最后一个位置。

i = mMaxNum - 1;

}

else

{ //如果大于其位置的最大值,说明已遍历完毕,超过了此数组合的最大值。

return;

}

}

}

void print()

{

cout<

cout<

}

private:

int mMaxNum;

vector mData;

int mCount;

int mAllCount;

};

intmain(int argc, char* argv[])

{

int n;

while(cin>>n)

{

pai2dui p(n);

p.run();

p.print();

}

return 0;

}

谢谢指教。

java编程题身高排队_身高排队算法-(较优解):12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?...相关推荐

  1. 【编程题目】12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,...

    80.阿里巴巴一道笔试题(运算.算法) 问题描述: 12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高, 问排列方式有多少种? 我的思路:输入从小到大排列的数字   ...

  2. java代码实现:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?...

    此题参考与其他人思路, 2个解题方式. 1. 1 /** 2 * 用java代码实现:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种? 3 * ...

  3. 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人 高,问排列方式有多少种?

    12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第一排比对应的第二排的人高,问排列方式有多少种? 思想:分析一下排列法,发现:每次安插第二排时,只要等第一排的选完了,再选最小值就行了.而选第 ...

  4. 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少

    分析问题: 显然可知,选人的顺序不影响最终结果数,所以我们对12个人从矮到高排序,编号1-12,依次放入队伍里. 1号肯定放在第0排第0列.假如1号放在任何其他位置,都需要有比他高的人放在0排0列,必 ...

  5. 12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

    /** *  */ public static void main(String[] args) { // TODO Auto-generated method stub InLineProblem( ...

  6. java编程题火车进站_火车进站

    119 难道只有我一个人觉得这题没说明白啥意思么? 发表于 2016-09-18 17:08:29 回复(40) 37 思路: 用栈模拟火车进出站:对进站序列排序得到字典序的第一组,处理完第一组,用 ...

  7. java编程实现arp欺骗_局域网 ARP 欺骗原理详解

    局域网 ARP 欺骗原理详解 ARP 欺骗是一种以 ARP 地址解析协议为基础的一种网络攻击方式, 那么什么是 ARP 地址解析协议: 首先我们要知道, 一台电脑主机要把以太网数据帧发送到同一局域网的 ...

  8. 12个高矮不同的人排成两排

    作者:baihacker  来源:http://hi.baidu.com/feixue http://hi.csdn.net/baihacker 问题描述:  12个高矮不同的人,排成两排,每排必须是 ...

  9. java编程求卡特兰数_卡特兰数(Catalan Number)

    卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列.该数在计算机专业中比较重要,有一些具体的应用实例.这篇文章主要分三部分: 卡特兰数递归式的含 ...

最新文章

  1. mysql 逻辑架构
  2. linux 网络监控指标,Linux监控一些指标
  3. flashisland in webdynpro
  4. 串行口通信c语言代码,问一下单片机串行口通信用c语言实现的问题
  5. shell获取本机ip
  6. paip.c#.net未能找到任何资源
  7. 关于动态库so的makefile编写
  8. debian系统离线安装iperf2
  9. 信息最全--MySQL循环插入测试用户数据--姓名
  10. Photoshop2020默认快捷键整理(Mac版)
  11. html页面中常见的特殊符号,收集的web页面html中常用的特殊符号大全
  12. 华为外包测试2年,不甘被替换,168天的学习转岗成正式员工
  13. CCKS2019总结
  14. MDCC 2016参会总结
  15. markdown添加目录
  16. 分享学JavaScript的第九天
  17. 星巴克男子的豆瓣网创业故事
  18. MySQL数据库 -- 库和表的操作
  19. 13 Scrapy框架介绍
  20. 南加大计算机本科学费,南加州大学学费多少 本科研究生学费介绍

热门文章

  1. resample函数
  2. 记一个cakephp调试问题
  3. android仿百度外卖波浪_Android实现波浪球效果
  4. GNSS原理和应用的第二周作业
  5. 【非线性光纤光学】,第四章第4题,我的解答,画出KDP晶体的角度调谐曲线
  6. 个人开发与日常使用装机必备软件、常用配置
  7. linux忘记root密码grab,安装完Linux后相关配置
  8. Android 手机信号强度上报机制1
  9. Windows驱动_文件系统微小过滤驱动之二驱动的安装和加载
  10. 宝塔面板安装使用教程