腾讯笔试题——小Q的歌单

小Q的歌单

1.问题描述:

小Q的歌单:
有X首长度为a的歌和Y首长度为b的歌,
现在需要组合有长度刚好是K的歌单
问有多少种组合方式,将结果模上1000000007

2.思路:

1.就是在长度为a的选择m首,在长度为b的中选择n首
2.计算其组合数即可

在这里:组合数的求法:

      (1)自己定义函数,按照公式求解即可。

      (2)组合数就是杨辉三角,对应的组合数就是杨辉三角中二维数组的特定位置的元素。 

3.代码:

//小Q的歌单:
//有X首长度为a的歌和Y首长度为b的歌,
//现在需要组合有长度刚好是K的歌单
//问有多少种组合方式,将结果模上1000000007

//思路:
//1.就是在长度为a的选择m首,在长度为b的中选择n首
//2.计算其组合数即可
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAX 1000000007

//求组合数
//在a里取b,有多少种方法
int com(int a, int b) {
	//先判断有没有0操作数
	if (a == 0 && b > a) {
		return 0;
	}
	if (b > a) {
		return 0;
	}
	if (b == 0 || b == a) {
		return 1;
	}
	//利用公式 Cab == a!/(b! * (a-b)!);
	int temp = a - b;
	int suma = 1;
	int sumb = 1;
	int sumab = 1;
	//求a的阶乘
	while (a) {
		suma = suma * a;
		a--;
	}
//	printf("suma = %d \n", suma);
	while (b) {
		sumb = sumb * b;
		b--;
	}
//	printf("sumb = %d\n", sumb);
	while (temp) {
		sumab = sumab * temp;
		temp--;
	}
//	printf("sumab = %d\n", sumab);
	int ret = 0;
	ret = suma / (sumb*sumab);
	return ret % MAX;
}


int main() {
	int x, a, y, b, k;

	printf("请依次输入:x首长度为a,y首长度为b,以及个单的长度k:\n");
	scanf("%d%d%d%d%d", &x, &a, &y, &b, &k);
	long long sum = 0;		//用来记录最后的大小
	int i = 0;
	while (i <= x) {
		//符合准则的选择方案
		if (k - (a*i) >= 0 && (k - (a*i)) % b == 0 && (k-(a*i))/b <= y) {
			long long p = com(x, i);
			long long q = com(y, (k - (a*i)) / b);
			sum += p * q;
			sum %= MAX;
		}
		++i;
	}

	printf("%lld\n", sum);
	system("pause");
	return 0;
}


 

发布了58 篇原创文章 · 获赞 43 · 访问量 4387

猜你喜欢

转载自blog.csdn.net/Wz_still_shuai/article/details/102013202
今日推荐