zoukankan      html  css  js  c++  java
  • 【编程题目】12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,

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

    我的思路:输入从小到大排列的数字  把数字4个分为一组 如下:

    min **** B

    A    **** max

    其中第一个数字一定是当前最小的, 最后一个数字一定是当前最大的。 其次,设位置A 、B,这样去掉这四个数字, 问题又变成了规模小一些的同样的问题。

    关键是A和B的确定,有很多种可能,我们依次尝试,如果不满足问题的条件了,就退出来,换一个数字。

    A的大小: 最小可能是当前输入的第【2】个数字, 最大可能是当前输入的第 【len(输入数字的个数)/2 + 1】 个数字,此外,如果它左边有数字,A必须比其左边的数字大。

    B的大小:最小的可能是第【len/2】个数字,最大的可能是第【len - 1】个数字,此外,如果它右边有数字,B必须比其右边的数字小。

    收获:被if else语句搞晕了, 如果用if else 则是选择关系, 几个条件只会检查其中一个。这里检查条件是要求全部都检查,所以不能加else。

    /*
    80.阿里巴巴一道笔试题(运算、算法)
    问题描述:
    12 个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,
    问排列方式有多少种?
    start time = 19:20
    end time = 第二天 10:56
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define N 12
    int way[2][6]; //存储方式
    
    /*
    min ***** B
    A   ***** Max
    */
    int TwoLines(int * num, int len) //输入数字必须从小到大排列
    {
        static int ways = 0;
        if(len == 0)
        {
            ways++;
            printf("way:%d
    ", ways);
            for(int j = 0; j < 2; j++)
            {
                for(int i = 0; i < N/2; i++)
                {
                    printf("%d ", way[j][i]);
                }
                printf("
    ");
            }
        }
        int minloc = (N - len)/4;  //当前最小数字的位置
        int maxloc = (N + len)/4 - 1; //当前最大数字的位置
        way[0][minloc] = num[0];
        way[1][maxloc] = num[len - 1];
    
        int Bminloc = len / 2 - 1;  //B最小可能的取值在num数组中的位置
        int Bmaxloc = len - 2;
        int Aminloc = 1;
        int Amaxloc = len/2;
    
        
        for(int b = Bminloc; b <= Bmaxloc; b++)
        {
            for(int a = Aminloc; a <= Amaxloc; a++)
            {
                if(a == b ) //数字不能相同
                {
                    continue;
                }
                if(maxloc < N/2 - 1)  //b位置的数字必须比它右边的数字小
                {
                    if( !(num[b] < way[0][maxloc + 1]) )
                    {
                        continue;
                    }
                }
                if(minloc > 0) //a位置的数字必须比它左边的大
                {
                    if( !( num[a] > way[1][minloc - 1]))
                    {
                        continue;
                    }
                }
    
                way[0][maxloc] = num[b];
                way[1][minloc] = num[a];
                int * num2 = (int *)malloc((len - 4) * sizeof(int));
                int i, j;
                for(i = 1, j = 0; j < len - 4; i++)
                {
                    if(i == b || i == a)
                    {
                        continue;
                    }
                    num2[j] = num[i];
                    j++;
                }
    
                TwoLines(num2, len - 4);
                    
                free(num2);
    
        
            }
        }
        return ways;
    }
    
    int main()
    {
        int num[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
        int ways = TwoLines(num, N);
        return 0;
    }

    网上找到了一个非常好的解法:

    http://blog.csdn.net/hackbuteer1/article/details/7450250

    虽然与卡特兰数的关系没有看懂,但是解法看懂了。很有启发性 重点看。 尤其是其中二进制的应用。

    另附一个讲解二进制很好的博客:http://www.cnblogs.com/xianghang123/archive/2011/08/24/2152408.html

    //网上答案 http://blog.csdn.net/hackbuteer1/article/details/7450250
    #include <iostream>
    using namespace std;
    
    int bit_cnt(int n)
    {
        int result = 0;
        for (; n; n &= n-1, ++result);  //统计n中 1的个数  每次把最低位的1清零
        return result;
    }
    
    int main(void)
    {
        int F[6], B[6];
        int i,j,k,state,ok,ans = 0;
        for (state = 0; state < (1 << 12); ++state)
        {
            if (bit_cnt(state) == 6)
            {
                i = j = 0;
                for (int k = 0; k < 12; ++k)
                {
                    if(state&(1<<k))  //判断对应位是否为1
                        F[i++] = k;
                    else
                        B[j++] = k;
                }
                ok = 1;
                for (k = 0; k < 6; ++k)
                {
                    if (B[k] < F[k])   //B和F分别是从小到大排的 只要检查对应位置的相对大小是否符合要求即可
                    {
                        ok = 0;
                        break;
                    }
                }
                ans += ok;
            }
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    webstorm破解
    macos-WebStorm安裝
    CocoaPods安装与使用
    前端之HTML
    python调用百度语音(语音识别-斗地主语音记牌器)
    MySQL学习笔记(二)
    MySQL学习笔记(一)
    python网络编程
    计算机网络基础
    python之hashlib、configparser、logging模块
  • 原文地址:https://www.cnblogs.com/dplearning/p/3896708.html
Copyright © 2011-2022 走看看