腾讯笔试题——小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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值