奇迹

时间限制: 2 Sec  内存限制: 512 MB

 

题目描述

相信奇迹的人,本身就和奇迹一样了不起。——笛亚 《星游记》

我们称一个日期为一个八位数,第1~4位构成年,第5~6位构成月,第7~8位构成日,不足位数用0补足。同时,要求日期所代表的这一天真实存在,且年的范围为1~9999。

出现奇迹的日期都存在相同的特点:由“日”组成的两位数,由“月+日”组成的四位数,由“年+月+日”组成的八位数均为质数。但并不是所有存在这样特点的日期都一定会出现奇迹。

现在,你得到了一个可能会出现奇迹的日期,然而不幸的是这个日期却是残缺的,八位中可能有若干位无法确定。你需要知道这个日期有多少种可能,这样你才能做好充足的准备去迎接奇迹的到来。

输入

本题有多组数据。

第一行一个正整数T,表示数据组数。

接下来的T行,每行一个八位字符串。其中第i位如果为 -,则表示日期的第i位无法确定,否则表示日期的第i位为字符串中第i位上的数字。

输出

对每组数据,一行一个整数,表示答案。

样例输入:

2
53-7-3-7
20190629

样例输出:

6
0

提示
53-7-3-7 的  种可能的日期如下:
53070307
53070317
53170307
53370307
53570317
53770307

一共10个测试点,记c为八位字符串中 - 的个数。
对前9个测试点,在第i个测试点中保证c=i-1。
对100%的数据保证1≤T≤10。


 

这道题内存是512M,据说标程是一种128M,但是我不会写。

...

我的做法是DFS+欧拉筛+结构优化 说了标程是128M的大佬做的 我不会 

这只是补题部分,还有比赛时候大大小小交了十多次 (我以为难的是时间,最后居然是因为128M的内存)

这道题的难点和坑点有很多..比如题目描述的“1~9999”年 比如描述的“要求真实存在” 还有要求的是质数 也就是从10000000年开始到99991231结束的质数筛

1.闰年的二月份

2.大小月

3.不存在的日子

4.1不是质数

5.无未知时情况特判

(Register真好用)

..

#include<cstdio>
#include<iostream>
#include<cmath>
#define re register
using namespace std;
char s[15];
int a[10],ans,cnt,prime[100000010];
bool pp[100000010];
int v[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
inline bool check(){
 
 int year=a[0]*1000+a[1]*100+a[2]*10+a[3];
 int month=a[4]*10+a[5];
 int day=a[6]*10+a[7];
 
 if(year%4==0&&year%100!=0||year%400==0){
  v[2]=29;
 }else{
  v[2]=28;
 }
 if(year==0||month==0||month>12||day==0||day>v[month]){
   return false;
 }

  for(int i=0;i<=7;i++){
   if(a[i]==-1){
   return false;
   }
  }
 
 int rm=day;
    int qm=month*100+day;
    int tm=year*10000+month*100+day;
   
 if(pp[tm]==0&&pp[rm]==0&pp[qm]==0){
  return true;
 }
 

 return false;
}

inline void dfs(int x){
 if(x==8){
  if(check()==true){
   ans++;
  }
  return;
 }
 if(a[x]!=-1){
  dfs(x+1);
 }else{
  for(int i=0;i<=9;i++){
  a[x]=i;
  dfs(x+1);
  a[x]=-1;
  }
 }
}
int main(){
 pp[1]=1;
 for (re int i=2;i<=100000000;i++ ) {
        if(!pp[i]) prime[++cnt]=i;
        for (re int j=1;j<=cnt;j++ ) {
            if(prime[j]*i>100000000) break;
            pp[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
   
 int t;
 cin>>t;
 while(t--){
  
  cin>>s;
  ans=0;
  int ttttt=0;
  
  if(s[0]=='-'&&s[1]=='-'&&s[2]=='-'&&s[3]=='-'&&s[4]=='-'&&s[5]=='-'&&s[6]=='-'&&s[7]=='-'){
   cout<<55157<<endl;
   continue;
  }
  
  for(int i=0;i<=7;i++){
   if(s[i]!='-'){
    
    a[i]=s[i]-48; 
   }else{
    ttttt++;
    a[i]=-1;
   }
  }
  for(int i=0;i<=7;i++){
   if(s[i]=='-'){
    dfs(i);
   }
  }if(ttttt==0){
   if(check()==1){
    ans++;
   }
  }
  cout<<ans<<endl;
 }
 return 0;
}

 

posted @ 2019-07-17 12:24  Fylsea  阅读(317)  评论(0编辑  收藏  举报