【题解】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

发现一个周期内共有六十个数字,八个数字七,而 20220201120060=3370033520\dfrac{202202011200}{60} = 3370033520,也就是说,共有 3370033520×8=269602681603370033520 \times 8 = 26960268160 个七。

2. 题 B 思路分析

感谢 zhang_kevin 提供的文件

这种题由于对复杂度木有要求,所以其实可以先打一个 10810^8 以内的埃氏筛法(我不会欧筛,太菜了)。

然后越出精度的就单独处理就可以啦,单独处理也不会很多,因为 99.99%99.99\% 都是正确的,只有 0.01%0.01\% 是错误的。而两百万个数中就只有两百个数是错的,单独处理也不会花太长的时间。

#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;
}
posted @ 2023-01-01 22:11  邻补角-SSA  阅读(18)  评论(0)    收藏  举报  来源