腾讯2018春招技术类编程题汇总
1、翻转数列
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4..., 每隔m个符号翻转一次, 最初符号为'-';。
例如:n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
小Q现在希望你能帮他算算前n项和为多少。
输入描述: 输入包括两个整数n和m(2 <= n <= 109, 1 <= m), 并且满足n能被2m整除。
输出描述: 输出一个整数, 表示前n项和。
输入例子:8 2 输出例子:8 ;
题目解析:n=2,m=1时,有-1+2=1*1 n=4,m=1时,有-1+2=1, -3+4=1 n=4,m=2时,有 -1-2+3+4=4=2*2; ....... 利用数学归纳法,每2m个数字相加的和=m*m,翻转数列中有n/2m组这样的数,则总和为(n/2m)*(m*m)=(n/2)*m;
c++实现(vs2019):
#include<iostream> using namespace std; int main() { scanf_s("%d%d",&n,&m); int sum=0; if(n%(2*m)!=0) return -1; sum=(n/2)*m; printf("%d\n",sum); return 0; }
2、小Q的歌单
小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。
输入描述:
每个输入包含一个测试用例。每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。
输出描述:
输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。
示例1 输入 5
2 3 3 3
输出 9
题目解析:组成的歌单满足的要求有:Ai+bj=K (0<=i<=X,0<=j<=Y);
Ai<=K; (K-Ai)/b<=Y; (K-A*i)%b==0(确保长度相加等于K)
涉及到排列组合和杨辉三角:c(n,k)=c(n-1,k)+c(n-1,k-1);
c++实现
#include<iostream> using namespace std; long long c[105]c[105]; const int mod=1000000007; void Init() // 初始化 { c[0][0]=1; for(int i=1;i<=100;i++) { c[i][0]=1; for(int j=1;j<=100;j++ { c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; } } } int main() { int k,a,x,b,y; long long sum=0; Init(); scanf("%d",&k); scanf_s("%d%d%d%d",&a,&x,&b,&x); for(int i=0;i<=x;i++) { if(a*i<=k && (k-a*i)%b==0 && (k-a*i)/b<=y) sum=(sum+(c[x][i]*c[y][(k-a*i)/b)])%mod)%mod; } printf("%lld\n",sum); return 0; }