ZOJ_3950_How Many Nines 解题报告及如何对程序进行测试修改

The 17th Zhejiang University Programming Contest Sponsored by TuSimple

Solution:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 int main()
  5 {
  6     long month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  7     long month_leap[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
  8     long tmonth[13],tmonth_leap[13];
  9     long t,i,j,k,l,s,g,y1,m1,d1,y2,m2,d2,run1,run2,ans=0;
 10     long ge[10000]={0},line[10000];
 11     tmonth[0]=0;
 12     tmonth_leap[0]=0;
 13     for (i=1;i<12;i++)
 14     {
 15         tmonth[i]=tmonth[i-1]+month[i];
 16         tmonth_leap[i]=tmonth_leap[i-1]+month_leap[i];
 17     }
 18     //between 2000-01-01 and 9999-12-31
 19     //the number of "9" in a year(do in advance)
 20     for (i=2;i<=9;i++)
 21         for (j=0;j<=9;j++)
 22             for (k=0;k<=9;k++)
 23                 for (l=0;l<=9;l++)
 24                 {
 25                     s=i*1000+j*100+k*10+l;
 26                     //the number of 9 in "ijkl"
 27                     g=((i==9)+(j==9)+(k==9)+(l==9));
 28                     //year(days in a year)
 29                     //+month(3*12,except February)
 30                     //+day(September)
 31                     if (s%4==0 && (s%100!=0 || s%400==0))
 32                         ge[s]=366*g+36+30;
 33                     else
 34                         ge[s]=365*g+35+30;
 35                 }
 36     //line[i]:the number of "9" in year 2000~i
 37     line[1999]=0;
 38     for (i=2000;i<=9999;i++)
 39         line[i]=line[i-1]+ge[i];
 40     scanf("%ld",&t);
 41     for (l=1;l<=t;l++)
 42     {
 43         scanf("%ld%ld%ld%ld%ld%ld",&y1,&m1,&d1,&y2,&m2,&d2);
 44         //year [y1,y2)      "[":included "(":not included
 45         ans=line[y2-1]-line[y1-1];
 46 
 47         //1 delete y1.1.1~y1.m1.(d1-1)
 48         g=(y1%10==9)+(y1/10%10==9)+(y1/100%10==9)+(y1/1000%10==9);
 49         //judge if loop year or not
 50         if (y1%4==0 && (y1%100!=0 || y1%400==0))
 51             run1=1;
 52         else
 53             run1=0;
 54         //year(days in year y1)
 55         if (run1==1)
 56             ans-=g*tmonth_leap[m1-1];
 57         else
 58             ans-=g*tmonth[m1-1];
 59         ans-=(d1-1)*g;
 60 
 61         //month
 62         ans-=(m1-1)*3;
 63         if (d1>=30)
 64             ans-=3;
 65         else if (d1>=20)
 66             ans-=2;
 67         else if (d1>=10)
 68             ans-=1;
 69         //February
 70         if (run1==0 && m1>2)
 71             ans++;
 72         //month
 73         if (m1>9)
 74             ans-=30;
 75         else if (m1==9)
 76             ans-=(d1-1);
 77 
 78         //2 add y2.1.1~y2.m2.d2
 79         g=(y2%10==9)+(y2/10%10==9)+(y2/100%10==9)+(y2/1000%10==9);
 80         if (y2%4==0 && (y2%100!=0 || y2%400==0))
 81             run2=1;
 82         else
 83             run2=0;
 84         if (run2==1)
 85             ans+=g*tmonth_leap[m2-1];
 86         else
 87             ans+=g*tmonth[m2-1];
 88         ans+=d2*g;
 89 
 90         ans+=(m2-1)*3;
 91         if (d2>=29)
 92             ans+=3;
 93         else if (d2>=19)
 94             ans+=2;
 95         else if (d2>=9)
 96             ans+=1;
 97         if (run2==0 && m2>2)
 98             ans--;
 99 
100         if (m2>9)
101             ans+=30;
102         else if (m2==9)
103             ans+=d2;
104 
105         printf("%ld\n",ans);
106     }
107     return 0;
108 }

感想:

正确题数机制:
1.认真看题,不要漏掉一些特殊情况。
2.多设数据,查看自己的程序是否完善。
3.对于渣渣,还是从简单题做起,不要对繁琐的模拟题丧失耐心,因为这是你得分的关键。

尤其是这道模拟题,细心加耐心

 

当你做出这道题提交上去时WrongAnswer,然后看了几遍自己程序,修改了一下,然后提交上去,还是WrongAnswer时,你的内心是崩溃的!

错误一般是:

1.漏掉一些特殊点

2.变量,下标写错

 

这时你可以这样做:

1.在网上找一份对的程序(亲自提交一下)

2.对自己的程序和标程创建文件流

(网上别人的程序)

  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <vector>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <set>
  8 #include <math.h>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <iomanip>
 12 #include <map>
 13 #define INF 0x3f3f3f3f
 14 #define MAXN 1005
 15 #define Mod 99999999
 16 using namespace std;
 17 int num[10005];
 18 int count9(int n)
 19 {
 20     int cnt=0;
 21     while(n!=0)
 22     {
 23         if(n%10==9)
 24             cnt++;
 25         n/=10;
 26     }
 27     return cnt;
 28 }
 29 bool isleap(int y)
 30 {
 31     if((y%4==0&&y%100!=0)||y%400==0)
 32         return true;
 33     return false;
 34 }
 35 void Init()
 36 {
 37     int sum=0;
 38     for(int i=2000; i<=9999; ++i)
 39     {
 40         if(isleap(i))
 41             sum=count9(i)*366;
 42         else
 43             sum=count9(i)*365;
 44         sum+=30;
 45         sum+=11*3;
 46         if(isleap(i))
 47             sum+=3;
 48         else
 49             sum+=2;
 50         num[i]=sum;
 51     }
 52 }
 53 int mon1[]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
 54 int mon2[]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
 55 int main()
 56 {
 57     FILE *in=fopen("C:\\Users\\Lenovo\\Desktop\\in.txt","r");
 58     FILE *out=fopen("C:\\Users\\Lenovo\\Desktop\\out_standard.txt","w");
 59     Init();
 60     int t;
 61     //scanf("%d",&t);
 62     fscanf(in,"%d",&t);
 63     while(t--)
 64     {
 65         int y1,m1,d1,y2,m2,d2;
 66         int ans=0;
 67         //scanf("%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2);
 68         fscanf(in,"%d%d%d%d%d%d",&y1,&m1,&d1,&y2,&m2,&d2);
 69         if(y1==y2)
 70         {
 71             int days=0;
 72             for(int i=m1+1; i<m2; ++i)
 73             {
 74                 if(i==2&&isleap(y1))
 75                     ans+=3;
 76                 else if(i==2&&!isleap(y1))
 77                     ans+=2;
 78                 else if(i==9)
 79                     ans+=33;
 80                 else
 81                     ans+=3;
 82                 if(!isleap(y1))
 83                     days+=mon1[i];
 84                 else
 85                     days+=mon2[i];
 86             }
 87             if(m1==m2)
 88             {
 89                 for(int i=d1; i<=d2; ++i)
 90                 {
 91                     ans+=count9(i);
 92                     days++;
 93                     if(m1==9)
 94                         ans++;
 95                 }
 96                 ans=ans+days*count9(y1);
 97                 //printf("%d\n",ans);
 98                 fprintf(out,"%d\n",ans);
 99             }
100             else
101             {
102                 if(!isleap(y1))
103                 {
104                     for(int i=d1; i<=mon1[m1]; ++i)
105                     {
106                         ans+=count9(i);
107                         days++;
108                         if(m1==9)
109                             ans++;
110                     }
111                 }
112                 else
113                 {
114                     for(int i=d1; i<=mon2[m1]; ++i)
115                     {
116                         ans+=count9(i);
117                         days++;
118                         if(m1==9)
119                             ans++;
120                     }
121                 }
122                 for(int i=1; i<=d2; ++i)
123                 {
124                     ans+=count9(i);
125                     days++;
126                     if(m2==9)
127                         ans++;
128                 }
129                 ans=ans+days*count9(y1);
130                 //printf("%d\n",ans);
131                 fprintf(out,"%d\n",ans);
132             }
133         }
134         else
135         {
136             for(int i=y1+1; i<y2; ++i)
137                 ans+=num[i];
138             int days1=0,days2=0;
139             for(int i=m1+1; i<=12; ++i)
140             {
141                 if(i==2&&isleap(y1))
142                     ans+=3;
143                 else if(i==2&&!isleap(y1))
144                     ans+=2;
145                 else if(i==9)
146                     ans+=33;
147                 else
148                     ans+=3;
149                 if(!isleap(y1))
150                     days1+=mon1[i];
151                 else
152                     days1+=mon2[i];
153             }
154             if(!isleap(y1))
155             {
156                 for(int i=d1; i<=mon1[m1]; ++i)
157                 {
158                     ans+=count9(i);
159                     days1++;
160                     if(m1==9)
161                         ans++;
162                 }
163             }
164             else
165             {
166                 for(int i=d1; i<=mon2[m1]; ++i)
167                 {
168                     ans+=count9(i);
169                     days1++;
170                     if(m1==9)
171                         ans++;
172                 }
173             }
174             ans=ans+days1*count9(y1);
175 
176             for(int i=1; i<m2; ++i)
177             {
178                 if(i==2&&isleap(y2))
179                     ans+=3;
180                 else if(i==2&&!isleap(y2))
181                     ans+=2;
182                 else if(i==9)
183                     ans+=33;
184                 else
185                     ans+=3;
186                 if(!isleap(y2))
187                     days2+=mon1[i];
188                 else
189                     days2+=mon2[i];
190             }
191             for(int i=1; i<=d2; ++i)
192             {
193                 ans+=count9(i);
194                 days2++;
195                 if(m2==9)
196                     ans++;
197             }
198             ans=ans+days2*count9(y2);
199             //printf("%d\n",ans);
200             fprintf(out,"%d\n",ans);
201         }
202     }
203 
204     fclose(in);
205     fclose(out);
206     return 0;
207 }

自己的程序(目前是错的):

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 int main()
  5 {
  6     FILE *in=fopen("C:\\Users\\Lenovo\\Desktop\\in.txt","r");
  7     FILE *out=fopen("C:\\Users\\Lenovo\\Desktop\\out.txt","w");
  8     long month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  9     long month_leap[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
 10     long tmonth[13],tmonth_leap[13];
 11     long t,i,j,k,l,s,g,y1,m1,d1,y2,m2,d2,run1,run2,ans=0;
 12     long ge[10000]={0},line[10000];
 13     tmonth[0]=0;
 14     tmonth_leap[0]=0;
 15     for (i=1;i<12;i++)
 16     {
 17         tmonth[i]=tmonth[i-1]+month[i];
 18         tmonth_leap[i]=tmonth_leap[i-1]+month_leap[i];
 19     }
 20     //2000-01-01 and 9999-12-31
 21     for (i=2;i<=9;i++)
 22         for (j=0;j<=9;j++)
 23             for (k=0;k<=9;k++)
 24                 for (l=0;l<=9;l++)
 25                 {
 26                     s=i*1000+j*100+k*10+l;
 27                     g=((i==9)+(j==9)+(k==9)+(l==9));
 28                     if (s%4==0 && (s%100!=0 || s%400==0))
 29                         ge[s]=366*g+36+30;
 30                     else
 31                         ge[s]=365*g+35+30;
 32                 }
 33     line[1999]=0;
 34     for (i=2000;i<=9999;i++)
 35         line[i]=line[i-1]+ge[i];
 36     //scanf("%ld",&t);
 37     fscanf(in,"%ld",&t);
 38     for (l=1;l<=t;l++)
 39     {
 40         //scanf("%ld%ld%ld%ld%ld%ld",&y1,&m1,&d1,&y2,&m2,&d2);
 41         fscanf(in,"%ld%ld%ld%ld%ld%ld",&y1,&m1,&d1,&y2,&m2,&d2);
 42         ans=line[y2-1]-line[y1-1];
 43 
 44         g=(y1%10==9)+(y1/10%10==9)+(y1/100%10==9)+(y1/1000%10==9);
 45         if (y1%4==0 && (y1%100!=0 || y1%400==0))
 46             run1=1;
 47         else
 48             run1=0;
 49         if (run1==1)
 50             ans-=g*tmonth_leap[m1-1];
 51         else
 52             ans-=g*tmonth[m1-1];
 53         ans-=(d1-1)*g;
 54 
 55         ans-=(m1-1)*3;
 56         if (d1>=30)
 57             ans-=3;
 58         else if (d1>=20)
 59             ans-=2;
 60         else if (d1>=10)
 61             ans-=1;
 62         if (run1==0 && m1>2)
 63             ans++;
 64 
 65         if (m1>9)
 66             ans-=30;
 67         else if (m1==9)
 68             ans-=(d1-1);
 69 
 70 
 71         g=(y2%10==9)+(y2/10%10==9)+(y2/100%10==9)+(y2/1000%10==9);
 72         if (y2%4==0 && (y2%100!=0 || y2%400==0))
 73             run2=1;
 74         else
 75             run2=0;
 76         if (run2==1)
 77             ans+=g*tmonth_leap[m2-1];
 78         else
 79             ans+=g*tmonth[m2-1];
 80         ans+=d2*g;
 81 
 82         ans+=(m2-1)*3;
 83         if (d2>=29)
 84             ans+=3;
 85         else if (d2>=19)
 86             ans+=2;
 87         else if (d2>=9)
 88             ans+=1;
 89         if (run2==0 && m2>2)
 90             ans--;
 91 
 92         if (m2>9)
 93             ans+=30;
 94         else if (m2==9)
 95             ans+=d1;
 96 
 97         //printf("%ld\n",ans);
 98         fprintf(out,"%ld\n",ans);
 99     }
100 
101     fclose(in);
102     fclose(out);
103     return 0;
104 }
105 /*
106 9999 1 19 9999 12 21
107 */

 

3.创建数据:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 #define num 100
 5 
 6 int main()
 7 {
 8     FILE *out=fopen("C:\\Users\\Lenovo\\Desktop\\in.txt","w");
 9     long month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
10     long month_leap[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
11     long y1,m1,d1,y2,m2,d2,i,t;
12     srand(time(NULL));
13     fprintf(out,"%ld\n",num);
14     for (i=1;i<=num;i++)
15     {
16         y1=2000+rand()%8000;
17         y2=2000+rand()%8000;
18         if (y1>y2)
19         {
20             t=y1;
21             y1=y2;
22             y2=t;
23         }
24         m1=rand()%12+1;
25         m2=rand()%12+1;
26         if (y1==y2 && m1>m2)
27         {
28             t=m1;
29             m1=m2;
30             m2=t;
31         }
32         if (y1%4==0 && (y1%100!=0 || y1%400==0))
33             d1=rand()%month_leap[m1]+1;
34         else
35             d1=rand()%month[m1]+1;
36         if (y2%4==0 && (y2%200!=0 || y2%400==0))
37             d2=rand()%month_leap[m2]+1;
38         else
39             d2=rand()%month[m2]+1;
40         if (y1==y2 && m1==y2 && d1>d2)
41         {
42             t=d1;
43             d1=d2;
44             d2=t;
45         }
46         fprintf(out,"%ld %ld %ld %ld %ld %ld\n",y1,m1,d1,y2,m2,d2);
47     }
48     fclose(out);
49     system("C:\\Users\\Lenovo\\Desktop\\test_c\\bin\\Debug\\test_c.exe");
50     system("C:\\Users\\Lenovo\\Desktop\\The_17th_Zhejiang_University_Programming_Contest_Sponsored_by_TuSimple\\c_sumbit\\bin\\Debug\\c_sumbit.exe");
51     system("C:\\Users\\Lenovo\\Desktop\\Judge_Correct\\bin\\Debug\\Judge_Correct.exe");
52 
53     return 0;
54 }

4.判断对错程序(自己程序与标准程序输出的区别,具体到哪一行是错的):

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main()
 5 {
 6     FILE *in1=fopen("C:\\Users\\Lenovo\\Desktop\\out.txt","r");
 7     FILE *in2=fopen("C:\\Users\\Lenovo\\Desktop\\out_standard.txt","r");
 8 
 9     long x,y,ans=0;
10 
11     while (fscanf(in1,"%ld",&x)!=EOF && fscanf(in2,"%ld",&y)!=EOF)
12     {
13         ans++;
14         if (x!=y)
15         {
16             printf("Line %ld !",ans);
17             printf("Wrong\n");
18             fclose(in1);
19             fclose(in2);
20             return 0;
21         }
22     }
23     if (fscanf(in1,"%ld",&x)!=EOF || fscanf(in2,"%ld",&y)!=EOF)
24     {
25         printf("Wrong\n");
26         fclose(in1);
27         fclose(in2);
28         return 0;
29     }
30     printf("Correct\n");
31     fclose(in1);
32     fclose(in2);
33     return 0;
34 }

5.执行程序,查看自己程序的错误

Output(etc):

Line 5 !

Wrong

6.查看错误的答案所对应的数据有什么共通的地方(那个地方就是你错误所在的地方),修改程序,直到自己程序是对的(多运行几次,因为数据是随机生成的)。

 

建议:

1.像这种模拟题提交前自己重新过一遍自己的程序,多设置几个特殊(特殊情况)和普遍(多种多样)的测试点。

2.平时做题注意收藏题目数据和官方解题报告,做一道题真正的收获是发现不足(没测试数据会让你卡在同一个地方)和学习新知识和方法(别人的解题过程)。

 

posted @ 2017-04-12 00:12  congmingyige  阅读(362)  评论(0编辑  收藏  举报