騰訊筆試題——小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;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章