JOJ 1042: Ambiguous Dates

来源:互联网 发布:腾讯视频连不上网络 编辑:程序博客网 时间:2024/06/05 19:15

这个题目的复杂性主要表现在细节太多了。其实不需要使用什么大的或者是复杂的算法。主要还是程序逻辑是否清晰。代码先贴出来。以后再写流程。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. char *token1,*token2,*token3,date[12];
  5. char sep[]="///-.,";
  6. int n,sc=0,ambi_date[2048],number,y,m,d;
  7. unsigned short days[2][13]={
  8.     0,31,28,31,30,31,30,31,31,30,31,30,31,
  9.     0,31,29,31,30,31,30,31,31,30,31,30,31
  10. };
  11. const int debug=0;
  12. void solve();
  13. void parse(char *token1,char *token2,char *token3);
  14. void print();
  15. void d_parse(int d1,int d2,int d3);
  16. void countDays(int y,int m,int d);
  17. int precheck(char *year,char *month,char *day);
  18. int check(int y,int m,int d);
  19. int isLeapYear(int y);
  20. int main() {
  21.     if(debug) {
  22.         freopen("in.txt","r",stdin);
  23.         freopen("out.txt","w",stdout);
  24.     }
  25.     scanf("%d",&n);
  26.     while(n--) {
  27.         scanf("%s",date);
  28.         sc++; number=0;
  29.         solve();
  30.     }
  31.     return 0;
  32. }
  33. void solve() {
  34.     int len=strlen(date),i,j;
  35.     /*
  36.     token1=strtok(date,sep);
  37.     if(token1 && strlen(token1)!=len) {
  38.         token2=strtok(NULL,sep);
  39.         token3=strtok(NULL,sep);
  40.         if(token1&&token2&&token3)
  41.         parse(token1,token2,token3);
  42.         else { print(); return; }
  43.     } */
  44.     for(i=0;i<len;i++) if(!isdigit(date[i])) break;
  45.     if(i<len) {
  46.         y=m=d=0;
  47.         for(j=0;j<i;j++)y=y*10+(date[j]-'0');
  48.         for(j=i+1;date[j]!=date[i];j++)m=m*10+(date[j]-'0');
  49.         for(j=j+1;j<len;j++)d=d*10+(date[j]-'0');
  50.         countDays(y,m,d);
  51.         countDays(y,d,m);
  52.         countDays(m,y,d);
  53.         countDays(m,d,y);
  54.         countDays(d,y,m);
  55.         countDays(d,m,y);
  56.     } else {
  57.         if(len==8) {
  58.             d_parse(4,2,2);
  59.             d_parse(2,4,2);
  60.             d_parse(2,2,4);
  61.         } else if(len==7) {
  62.             d_parse(4,2,1);
  63.             d_parse(4,1,2);
  64.             d_parse(2,4,1);
  65.             d_parse(2,1,4);
  66.             d_parse(1,4,2);
  67.             d_parse(1,2,4);
  68.         } else if(len==6) {
  69.             d_parse(4,1,1);
  70.             d_parse(1,4,1);
  71.             d_parse(1,1,4);
  72.             d_parse(2,2,2);
  73.         } else if(len==5) {
  74.             d_parse(2,2,1);
  75.             d_parse(2,1,2);
  76.             d_parse(1,2,2);
  77.         } else if(len==4) {
  78.             d_parse(2,1,1);
  79.             d_parse(1,2,1);
  80.             d_parse(1,1,2);
  81.         } else if(len==3) {
  82.             d_parse(1,1,1);
  83.         }
  84.     }
  85.     print();
  86. }
  87. void parse(char *token1,char *token2,char *token3) {
  88.     int i;
  89.     y=m=d=0;
  90.     for(i=0;token1[i];i++) y=y*10+(token1[i]-'0');
  91.     for(i=0;token2[i];i++) m=m*10+(token2[i]-'0');
  92.     for(i=0;token3[i];i++) d=d*10+(token3[i]-'0');
  93.     if(precheck(token1,token2,token3))
  94.         countDays(y,m,d);
  95.     if(precheck(token1,token3,token2))
  96.         countDays(y,d,m);
  97.     if(precheck(token2,token1,token3))
  98.         countDays(m,y,d);
  99.     if(precheck(token2,token3,token1))
  100.         countDays(m,d,y);
  101.     if(precheck(token3,token1,token2))
  102.         countDays(d,y,m);
  103.     if(precheck(token3,token2,token1))
  104.         countDays(d,m,y);
  105. }
  106. void d_parse(int d1,int d2,int d3) {
  107.     char tt1[12],tt2[12],tt3[12];
  108.     int i=0,j; 
  109.     while(i<d1){tt1[i]=date[i];i++;}
  110.     tt1[i]='/0'; j=0;
  111.     while(i<d2+d1)tt2[j++]=date[i++];
  112.     tt2[j]='/0';j=0;
  113.     while(date[i])tt3[j++]=date[i++];
  114.     tt3[j]='/0';
  115.     parse(tt1,tt2,tt3);
  116. }
  117. void print() {
  118.     int a,b,c;
  119.     printf("Scenario #%d:/n",sc);
  120.     debug?printf("date : %s/n", date):1;
  121.     if(number==0) 
  122.         printf("Illegal date/n");
  123.     else {
  124.         for(a=1;a<number;a++) {
  125.             c=ambi_date[a];
  126.             for(b=a-1;b>=0&&ambi_date[b]>c;b--)
  127.                 ambi_date[b+1]=ambi_date[b];
  128.             ambi_date[b+1]=c;
  129.         }
  130.         printf("%d/n",ambi_date[0]);
  131.         for(a=1;a<number;a++)
  132.             if(ambi_date[a]!=ambi_date[a-1])
  133.             printf("%d/n",ambi_date[a]);
  134.         number=0;
  135.     }
  136.     printf("/n");
  137. }
  138. void countDays(int y,int m,int d) {
  139.     int i,f,dt=0,base=110246;
  140.     if(!check(y,m,d)) return;
  141.     if(y<100) {
  142.         for(i=1700;i<=2200;i+=100)
  143.             countDays(y+i,m,d);
  144.     }
  145.     if(y<1700) return;
  146.     for(i=1700;i<y;i++) {
  147.         if(isLeapYear(i)) dt+=366;
  148.         else dt+=365;
  149.     }
  150.     f=isLeapYear(y);
  151.     for(i=1;i<m;i++) dt += days[f][i];
  152.     dt+=d;
  153.     ambi_date[number++]=dt-base;
  154. }
  155. int check(int y,int m,int d) {
  156.     int f;
  157.     if(y>=100&&y<1700 || y>2299) return 0;
  158.     if(m<1 || m>12) return 0;
  159.     if(d<1 || d>31) return 0;
  160.     f=isLeapYear(y);
  161.     if(d>days[f][m]) return 0;
  162.     return 1;
  163. }
  164. int isLeapYear(int y) {
  165.     return ((y%4==0&&y%100!=0) || (y%400==0));
  166. }
  167. int precheck(char *year,char *month,char *day){
  168.     int ly,lm,ld;
  169.     ly=strlen(year);
  170.     lm=strlen(month);
  171.     ld=strlen(day);
  172.     if(ly==3 || ly>=5) return 0;
  173.     if(lm>=3)return 0;
  174.     if(ld>=3)return 0;
  175.     if(ly==4 && ly+lm+ld==8) {
  176.         lm=0;
  177.         for(ld=0;ld<ly;ld++) lm=lm*10+year[ld]-'0';
  178.         if(lm<100) return 0;
  179.     }
  180.     return 1;
  181. }