【题解】P8790 题解
P8790 题解
1. 题 A 思路分析
找周期的题目,既可以手推也可以机算。但基本原理都是按公式递推,一个一个枚举找周期。
这里给出机算代码:
long long a = 1, b = 1, c; //a代表前二项,b代表前一项,c代表目前
cout << a << "," << b << ",";
while(true)
{
c = (a + b) % 10; //算出目前的个位
cout << c << ",";/
if((b % 10 == 1) && (c % 10 == 1))
{
cout << "stoped" << endl; // 1 1 后面必为周期(回到了开头,可继续递推)
return 0;
}
a = b;
b = c;
a %= 10; //注意取个位,防止溢出
b %= 10; //注意取个位,防止溢出
}
注意本代码是检测到了后一个周期的开头两个数,所以要输出数列的末尾两个数不算在周期内。
递推得到周期:
1,1,2,3,5,8,3,1,4,5,9,4,3,7,0,7,7,4,1,5,6,1,7,8,5,3,8,1,9,0,9,9,8,7,5,2,7,9,6,5,1,6,7,3,0,3,3,6,9,5,4,9,3,2,5,7,2,9,1,0
发现一个周期内共有六十个数字,八个数字七,而 ,也就是说,共有 个七。
2. 题 B 思路分析
感谢 zhang_kevin 提供的文件。
这种题由于对复杂度木有要求,所以其实可以先打一个 以内的埃氏筛法(我不会欧筛,太菜了)。
然后越出精度的就单独处理就可以啦,单独处理也不会很多,因为 都是正确的,只有 是错误的。而两百万个数中就只有两百个数是错的,单独处理也不会花太长的时间。
#include <iostream>
#include <cstdio>
using namespace std;
bool flag[N];
int main()
{
memset(flag, true, sizeof(flag));
flag[0] = flag[1] = false;
for (int i = 2; i <= (N - 10); i++)
{
if(flag[i])
{
for(int j = 2;j <= (N - 10) / i;j++)
{
flag[i * j] = false;
}
}
}
//埃氏筛法
freopen("prime.txt", "r", stdin); //源文件
freopen("proc.txt", "w", stdout); //需要处理的文件
freopen("cnt.txt", "w", stderr); //满足范围条件的数中质数的个数
long long t, cnt = 0;
while(cin >> t)
{
cin >> t;
if(t > (N - 10))
{
cout << t << endl;
continue;
}
else if(flag[t])
{
cnt++;
}
}
cerr << cnt << endl;
return 0;
}
大概数了一下,一共有一百七十个数不符合范围条件,也不多了其实。
下面是处理范围外质数的代码。
bool pd(long long num)
{
if(num == 2) //特判偶质数
{
return true;
}
if(num % 2 == 0 || num < 2) //特判大于二的偶数和小于二的数
{
return false;
}
else
{
for(long long i = 3;i * i <= num;i += 2) //偶数不可能是质数,默认跳过
{
if(num % i == 0)
{
return false;
}
}
return true;
}
}
int main()
{
freopen("proc.txt", "r", stdin);
long long t, cnt = 0;
while(cin >> t)
{
if(pd(t))
{
cnt++;
}
}
cout << cnt << endl;
return 0;
}
计算后一共 342693 个。
把答案套入模板即可。
代码
#include<iostream>
using namespace std;
int main() {
string ans [] = {
"26960268160", // 双引号中替换为 A 题的答案
"342693", // 双引号中替换为 B 题的答案
};
char T;
cin >> T;
cout << ans[T - 'A'] << endl;
return 0;
}

浙公网安备 33010602011771号