牛客网算法学习笔记-排列组合

来源:互联网 发布:c语言怎么样 编辑:程序博客网 时间:2024/05/16 01:26

在XxY的方格中,以左上角格子为起点,右下角格子为终点,每次只能向下走或者向右走,请问一共有多少种不同的走法

给定两个正整数int x,int y,请返回走法数目。保证x+y小于等于12。

测试样例:
2,2
返回:2
横向要走X-1步,纵向要走Y-1步,总共需要走,X+Y-2步,其中有X-1横向。C{x-1,x+y-2}
class Robot {public:    int countWays(int x, int y) {        // write code here        if(x==1&&y==1)            return 0;                return C(x-1,x+y-2);    }        int C(int m,int n){                long a = n - m ;        long result = 1;        long temp1 = 1;        long  temp2 = 1;        for(int i = 1 ; i<=n;i++){            result = result *i;        }                for(int i = 1;i<=m;i++){            temp1 = temp1 * i;        }                for(int i = 1 ; i <=a;i++){            temp2 = temp2 * i ;        }        return result/(temp1*temp2);                    }};

n个人站队,他们的编号依次从1到n,要求编号为a的人必须在编号为b的人的左边,但不要求一定相邻,请问共有多少种排法?第二问如果要求a必须在b的左边,并且一定要相邻,请问一共有多少种排法?

给定人数n及两个人的编号ab,请返回一个两个元素的数组,其中两个元素依次为两个问题的答案。保证人数小于等于10。

测试样例:
7,1,2
返回:[2520,720]
第一个:所有的排列组合中一半a在b左边,一半a在b右边
第二个:将两个人看做一个整体,所以一共只有N-1个人的全排列
class StandInLine {
public:
    vector<int> getWays(int n, int a, int b) {
        // write code here
        int result1 = 1;
        for (int i = 1;i<=n;i++){
            result1 = result1 * i;
        }
        int result2 = 1;
        for(int i = 1;i<=n-1;i++){
            result2  = result2 * i;
        }
        vector<int> result;
        result.push_back(result1/2);
        result.push_back(result2);
        return result;
    }
};
9.4(思路比较模糊)

A(A也是他的编号)是一个孤傲的人,在一个n个人(其中编号依次为1到n)的队列中,他于其中的标号为b和标号c的人都有矛盾,所以他不会和他们站在相邻的位置。现在问你满足A的要求的对列有多少种?

给定人数n和三个人的标号A,bc,请返回所求答案,保证人数小于等于11且大于等于3。

测试样例:
6,1,2,3
288
用排除的方式,先将A放在最左边,AB相连的情况,再将A放在最右边,BA相连的情况,然后还有AC,CA。但是这种排列方式中会有A出现在中间的情况,那么就会重复减CAB,和BAC的情况,所以要加回来。
class LonelyA {public:    int getWays(int n, int A, int b, int c) {        // write code here        if(n==3)            return 0;                int result = 1;        int part1 = 1;        int part2 = 1;        int minglePart = 1;        for(int i = 1 ; i<=n;i++){            result = result * i;        }        for(int i = 1;i<=n - 1;i++){            part1 = part1 * i;        }        for(int i = 1;i<=n-1 ; i++){            part2 = part2 *i;        }        for(int i = 1;i<=n-2; i++){            minglePart = minglePart * i;        }        minglePart = minglePart * 2;        result = result - 2*(part1 + part2) +minglePart;        return result;    }};

n颗相同的糖果,分给m个人,每人至少一颗,问有多少种分法。

给定nm,请返回方案数,保证n小于等于12,且m小于等于n。

测试样例:
10,3
返回:36
class Distribution {
public:
    int getWays(int n, int m) {
        // write code here
        if(n==m)
            return 1;
        return C(n-1,m-1);
    }
    int C(int n ,int m){
        int result =1 ;
        int part1 = 1;
        int part2 = 1;
        for(int i =1 ;i<=n;i++){
            result = result * i;
        }
        
        for(int i =1 ;i<= (n-m);i++){
            part1 = part1 * i;
        }
        for(int i = 1; i<=m;i++){
            part2 = part2 *i;
        }
        return result/(part1*part2);
    }
};
0 0
原创粉丝点击