非常好的一道题,方法对可以非常简单,如果写成大模拟就会很麻烦。思路是按照要求直接筛选出1到9999所有复合条件的,在对给出的数据求解时,如果用数据去一个一个寻找对应可能的日期就会比较麻烦,而如果直接遍历所有日期看是否与给出的日期相同那么就可以一个一个加出,非常简单,就是时间可能会长一点。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include <stack>
#define LL long long
using namespace std;
const int N = 1e6 + 10;
int moth[20]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int day[20]={0,3,5,7,11,13,17,19,23,29,31,37};//日期中的质数
int ans[666666],a[100],T,tot,num=0;
char s[10];
int prime(int x){
for(int i=2;i*i<=x;i++){
if(x%i==0)return 0;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
for(int i=1;i<=12;i++){
for(int j=1;moth[i]>=day[j];j++){
if(prime(i*100+day[j])==1){
a[++num]=i*100+day[j];
}
}
}
for(int i=4;i<=9999;i+=4){
if((i%100||!(i%400))&&prime(i*10000+229)){
ans[++tot]=i*10000+229;
}
}
for(int i=1;i<=9999;i++){
for(int j=1;j<=num;j++){
if(prime(i*10000+a[j])){
ans[++tot]=i*10000+a[j];
}
}
}
cin>>T;
while(T--){
cin>>(s+1);
int cnt=0;
for(int i=1,now,flag;i<=tot;i++){
now=ans[i],flag=1;
for(int j=8;j&&flag;j--,now/=10){
if(s[j]!='-'&&s[j]-'0'!=now%10){
flag=0;
}
}
cnt+=flag;
}
cout<<cnt<<'\n';
}
return 0;
}