赞
踩
传送门https://www.luogu.com.cn/problem/P5440
思路历程:很离谱的一题,在理论上并不困难,只要简单dfs+欧拉筛就能过。在一开始,我采用了倒着模拟的思路,用stoi函数,强转字符串,发现样例能跑,但是仍旧RE(现在仍未理解这样的原因),于是,我选择了另一种做法,反过来遍历。
下面是代码:
- #include<iostream>
- #include<algorithm>
- #include<cmath>
- #include<set>
- #include<string>
- using namespace std;
- const int N=1e8+5;
- int _;
- string s;
- int ans;
- bool nums[N];//这两行
- long long f[10000001],cot=0;//这两行是欧拉筛的板子
- int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//减少代码量,开一个月份数组
- bool check(int num){//检查年份符不符合逻辑
- int day=num%100;
- int month=(num/100)%100;
- int year=num/10000;
- if((year%4==0&&year%100!=0)||year%400==0){
- months[2]=29;
- }
- else months[2]=28;
- return year>=1&&year<=9999&&month>=1&&month<=12&&day>=1&&day<=months[month];
- }
-
- void dfs(int x,int num){//第x层,数字为num
- int sum;//记录每一层要加多少
- if(x==8&&check(num)&&!nums[num]&&!nums[num%10000]&&!nums[num%100]){//100和10000
- ans++;//2 4 8都要是素数
- }
- else if(x==8) return;//只要是8就返回
- else if(s[x]!='-'){
- sum=(s[x]-'0')*pow(10,7-x);//字符串转数字 要注意减去‘0’
- dfs(x+1,num+sum);
- }
- else{
- if(x==4){//特判优化,减少for的遍历(月份)
- for(int i=0;i<2;++i){
- sum=i*pow(10,7-x);
- dfs(x+1,sum+num);
- }
- }
- else if(x==6){//特判优化(日子)
- for(int i=0;i<4;++i){
- sum=i*pow(10,7-x);
- dfs(x+1,sum+num);
- }
- }
- else{
- for(int i=0;i<=9;++i){
- sum=i*pow(10,7-x);
- dfs(x+1,sum+num);
- }
- }
- }
-
- }
-
- void solve(){
- ans=0;
- cin>>s;
- dfs(0,0);(从第0层开始)
- cout<<ans<<endl;
- }
-
- int main(){
- nums[1]=true;//1不是素数 true就不是素数
- long long n=1e8;
- for(long long i=2;i<=n;i++)
- {
- if(!nums[i])
- f[cot++]=i;
- for(long long j=0;j<cot&&i*f[j]<=n;j++)
- {
- nums[f[j]*i]=true;
- if(i%f[j]==0)
- break;
- }
- }//从开头到这里就是一个欧拉筛的板子
- cin>>_;
- while(_--){
- solve();
- }
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。