小Q定义了一种数列称为翻转数列:
给定整数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项和。
输入例子1:
8 2
输出例子1:
8
解题思路:n为数组长度,m为翻转长度,题目要求n%(2m)=0,数组长度为翻转长度的两倍的倍数,
举个栗子:
n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
2m长度的和为 -1-2+3+4=》(-1+3)+(4-2)=22
n = 6, m = 3, 数列就是: -1, -2, -3, +4,+5, +6.
2m长度的和为 -1-2 -3 +4+5 +6=》(-1+4)+(-2+5)+(-3+6)=33
n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
2m长度的和为 -1+2=》(-1+2)=11
所以长度为n的数组有n/(2m)=k,就有几个结果为kmm
所以长度为n的和可表示为m^2(n/(2m)),可以简化为(mn)/2
代码:
#include<iostream>
using namespace std;
int main()
{
long long n,m;//n为个数,m是翻转长度
cin>>n>>m;
cout<<(m*n)/2;
return 0;
}
小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
解题思路:暴力求解法,通过率只有百分之七十,可能有边界条件未考虑到
#include<iostream>
#include<vector>
using namespace std;
long long getcombnum(int l1n, int k1, int l2n, int k2)//计算排列组合值 ,需要考虑k为0的情况
{
long long c1, c2;//存放l1,l2排列组合结果
long long mom = 1, son = 1;//存放分子分母
if (k1 == 0)
c1 = 1;
else {
mom = 1;
son = 1;
if(k1==l1n)
{
c1=1;
}
else{
for (int i = 1; i <= k1; ++i, --l1n)
{
son *= l1n;
mom *= i;
}
c1 = son / mom;
}
}
if (k2 == 0)
c2 = 1;
else {
mom = 1;
son = 1;
if(k2==l2n)
c2=1;
else
{
for (int i = 1; i <= k2; ++i, --l2n)
{
son *= l2n;
mom *= i;
}
c2 = son / mom;
}
}
return c1*c2;
}
int main()
{
int l1, l2, suml;//分别表示歌单1、2长度,和歌单歌单总长
int l1n, l2n;//歌单1、2数量
long long res = 0,temp;//最终结果
int s1, s2;//存放只用歌单1或2时需要的歌单最多个数 //int num1,num2;
vector<int> n1array;//存放长度为l1的歌的个数
vector<int> n2array;//存放长度为l2的歌的个数
cin >> suml >> l1 >> l1n >> l2 >> l2n;
if(l1==l2||suml<1||suml>1000||l1<1||l1>10||l1n<=0||l1n>100||l2<1||l2>10||l2n<=0||l2n>100)
return -1;
s1 = suml / l1;
s2 = suml / l2;
if (s1>l1n)//取它和该长度本身数量较小的一个
s1 = l1n;
if (s2>l2n)
s2 = l2n;
for (int i = 0; i<=s1; ++i)//i,j为长度为1或2的歌的个数对
{
for (int j = 0; j<=s2; ++j)
{
if ((i*l1 + j*l2) == suml)
{
n1array.push_back(i);
n2array.push_back(j);
break;
}
}
}
int size = n1array.size();
for (int i = 0; i<size; ++i)
{
temp = getcombnum(l1n, n1array[i], l2n, n2array[i]);
res += temp;
}
cout << res%1000000007;
return 0;
}