描述
数字序列定义如下:
f(1)=1,f(2)=1,f(n)=(A*f(n-1)+B*f(n-2))mod 7。
给定A、B和n,你要计算f(n)的值。
输入
输入由多个测试用例组成。每个测试用例在一行中包含3个整数A、B和n(1<=A、B<=1000、1<=n<=100000000)。三个零表示输入结束,不处理此测试用例。
输出
对于每个测试用例,在一行上打印f(n)的值。
样本输入
1 1 3
1 2 10
0 0
样本输出
2.
5.
常规解法
#include
#include
using namespace std;
int main() {
vector dp(100000001, -1);
int A, B, n;
while (cin >> A >> B >> n) {
if (A == 0 && B == 0 && n == 0) {
break;
}
dp[1] = 1;
dp[2] = 1;
for (int i = 3; i <= n; i++) {
dp[i] = (A * dp[i - 1] + B * dp[i - 2]) % 7;
}
cout << dp[n] << endl;
}
return 0;
}
由于数据太大,wa了
#include
using namespace std;
int res[1000]; // 定义一个数组用于存储计算结果
int main()
{
res[1]=res[2]=1; // 初始化数组的前两个值为1
int a,b,n; // 定义输入的三个整数A、B和n
while(cin>>a>>b>>n) // 循环读取输入
{
if(a==0&&b==0&&n==0) // 如果输入为三个0,则结束循环
break;
if(n==1||n==2) // 如果n为1或2,直接输出结果
cout<
Description
兴安黑熊在高中学习数学时,曾经知道这样一个公式:f(n)=1^2+2^2+3^2+.......+n^2,这个公式是可以化简的,化简后的结果是啥它却忘记了,也许刚上大二的你能记得。现在的问题是想要计算f(n)对1007取余的值,你能帮帮他吗?Input
输入数据有多组(不超过100组),每组一个数n. (1<=n <=1,000,000,000).Output
输出f(n)对1007取余的值。Sample Input
3 4 100Sample Output
14 30 1005
常规算法
#include
using namespace std;
const int MOD = 1007;
int main() {
int n;
while (cin >> n) {
long long sum = 0;
for (int i = 1; i <= n; ++i) {
sum = (sum + (long long)i * i) % MOD;
}
cout << sum << endl;
}
return 0;
}
当一个表达式对一个数取余的时候大概率存在周期,一般在三倍取模的数之内
(a+b)%c=(a%c+b%c)%c
(ab)%c=((a%c)(b%c))%c
ab%c=(a%c)b%c
#include
using namespace std;
int main()
{
long long int n;
while(cin>>n)
{
long long int n1=n,n2=n+1,n3=2*n+1;
long long int res;
//运用公式F(n)=(1/6*n*(n+1)*(2n+1))%1007
//对1/6的处理,拆成1/2*1/3,由题意一定能整除
if(n1%2==0)
n1=n1/2;
else
n2=n2/2;
if(n1%3==0)
n1=n1/3;
else if(n2%3==0)
n2=n2/3;
else
n3=n3/3;
res=((((n1%1007)*(n2%1007))%1007)*(n3%1007))%1007;//疯狂取模避免溢出
cout<
扩展欧几里得算法
//逆元做法
#include
typedef long long LL;
using namespace std;
void Ex_gcd(LL a, LL b, LL &x, LL &y)
{
if(b == 0)//递归出口
{x = 1;y = 0;return;}
Ex_gcd(b, a%b, x, y);
int t;
t=x;
x =y;
y = t-(a/b)*y;
}
int main()
{
LL a,b,x,y,n,ans;
Ex_gcd(6,1007,x,y);
x=(x+1007)%1007;
while(cin>>n)
{
ans=(n*(n+1))%1007;
ans=(ans*(2*n+1))%1007;
ans=(ans*x)%1007;//其实x=168
cout<
首先调用 `Ex_gcd(6,1007,x,y)` 求出 6在模 1007意义下的逆元 x,然后循环读入 n,计算 的值。根据公式 ,可以将计算过程拆分为三个部分,每个部分计算完之后都对 1007取模,最后再乘起来,最终的结果也要对 1007取模。其中,n(n+1)(2n+1) 可以直接用乘法计算,而 的逆元就是 x,因此可以直接用 x$乘以 n(n+1)(2n+1),而不必再除以6。
描述
还有另一种斐波那契数:F(0)=7,F(1)=11,F(n)=F(n-1)+F(n-2)(n>=2)。
输入
输入由一系列行组成,每行包含一个整数n。(n<1000000)。
输出
如果3等分为F(n),则打印单词“是”。
如果没有,请打印“否”字。
样本输入
0
1.
2.
3.
4.
5.
样本输出
nono
yes
no
no
no
//余数循环节 1,2,0,2,2,1,0,1 每8个数为1个循环
#include
//余数循环节 1,2,0,2,2,1,0,1 每8个数为1个循环
int main()
{
int n;
while(scanf("%d",&n)!=-1)
{
if(n%8==2||n%8==6)printf("yes\n");
else printf("no\n");
}
return 0;
}
Description
计算N!末尾有多少个0Input
输入数据有多组,每组1行,每行1个数N(10 <= N <=100000000)Output
在一行内输出N!末尾0的个数。Sample Input
10 100Sample Output
2 24
观察个位数的乘法,仅有25能出现0
因此把n!进行因式分解一对25末尾就有一个0
而n!中2的数量一定大于5的数量
因此即统计n!因式分解后出现几个5即可那么关键在于5的数量了那么该问题的实质是要求出1~100含有多少个5由特殊推广到一般的论证过程可得:
1、 每隔5个,会产生一个0,比如 5, 10 ,15,20
2 、每隔 5×5 个会多产生出一个0,比如 25,50,75,100
3 、每隔 5×5×5 会多出一个0,比如125.所以100!末尾有多少个零为:100/5+100/25=20+4=24那么1000!末尾有多少个零呢?
同理得: 1000/5+1000/25+1000/125=200+40+8=248
#include
using namespace std;
int main() {
int N;
while (cin >> N) {
int count = 0;
while (N >= 5) {
count += N / 5;
N /= 5;
}
cout << count << endl;
}
return 0;
}
Description
我们知道斐波那契数列的递推公式为f(n)=f(n-1)+f(n-2) n>=2 f(0)=0 f(1)=1; 那么,我们想知道f(n)%103的值是多少。Input
输入数据有多组,每组数据为一行,是一个整数n。Output
对于每组输入数据,输出一行,是一个整数,为f(n)%103的值。Sample Input
1 2 3 4 5 6Sample Output
1 1 2 3 5 8
#include
using namespace std;
int main() {
int f[208];
f[0] = 0;
f[1] = 1;
for (int i = 2; i <= 207; i++) {
f[i] = (f[i - 1] + f[i - 2]) % 103;
}
int n;
while (cin >> n)
cout << f[n % 208] << endl;
return 0;
}
Description
现在有一个数列的递推公式是g(n)=3*g(n-1)+g(n-2). g(1)=1,g(0)=0。 求g(n)%223的值。Input
输入数据有多组,每组数据为一行,是一个整数n。Output
对于每组输入数据,输出一行,是一个整数,为g(n)%223的值。Sample Input
1 2 3 4 5 6Sample Output
1 3 10 33 109 137
#include
using namespace std;
int main() {
int ans[448];
ans[0] = 0;
ans[1] = 1;
for (int i = 2; i <= 447; i++) {
ans[i] = 3 * ans[i - 1] + ans[i - 2];
ans[i] %= 223;
}
int n;
while (cin >> n)
cout << ans[n % 448] << endl;
return 0;
}
Description
如果有一个序列f(n)=a*f(n-1)+b*f(n-2),f(0)=0,f(1)=1。我们对于给定的系数a,b找到f(n)%107的值。Input
输入数据有多组,每组数据第一行有三个整数a,b(a>0,b>0),N,N代表接下来测试的数据数,接下来有N行,每行一个整数n。Output
对于在给定的系数a,b下对每个n输出每一个f(n)%107。Sample Input
3 1 6 1 2 3 4 5 6Sample Output
1 3 10 33 2 39
#include
using namespace std;
int f[1000000];
int main()
{
int a, b, N;
while (cin >> a >> b >> N) {
f[0] = 0;
f[1] = 1;
int i;
for (i = 2;; i++) {
f[i] = a * f[i - 1] + b * f[i - 2];
f[i] %= 107;
if (f[i] == 1 && f[i - 1] == 0)
break;
}
int len = i - 1;
int ans[len];
ans[0] = 0;
ans[1] = 1;
for (i = 2; i < len; i++) {
ans[i] = a * ans[i - 1] + b * ans[i - 2];
ans[i] %= 107;
}
while (N--) {
int n;
cin >> n;
cout << ans[n % len] << endl;
}
}
return 0;
}
Description
我们知道斐波那契数列的递推公式是f(n)=f(n-1)+f(n-2);现在老师给小明一个P,我们知道会有一个最小的m,使得f(n)%P=f(n+m)%P对每一个n成立,求出这个最小的m。Input
输入数据有多组,每组数据为一行,是一个整数P。(1
Output
对于每组输入数据,输出一行,是一个最小的整数m,使得f(n)%P=f(n+m)%P对每一个n成立。Sample Input
5 11 19 61 17Sample Output
20 10 18 60 36
#include
using namespace std;
int f[1000000];
int main()
{
int P;
while(cin>>P){
f[0]=0;
f[1]=1;
int i;
for(i=2;;i++){
f[i]=f[i-1]+f[i-2];
f[i]%=P;
if(f[i]==1&&f[i-1]==0)
break;
}
cout<