1008. 二哥买期货
Description
二哥想知道在一段时期内,一共有多少个交易日。期货交易日的限定如下:
- 周六、周日不能交易
- 元旦期间(1月1日)不能交易
- 五一劳动节期间(5月1日至3日)不能交易
- 十一国庆节期间(10月1日至7日)不能交易
- 没有在上述要求中提到的日期均可交易
Input Format
第一行有一个整数n,表示一共有n组数据。
每组数据都有一行,是两个用空格分开的日期,分别为开始日期和结束日期。日期格式为YYYY-MM-DD(比如2010-11-11);数据保证开始日期不晚于结束日期。
对于所有数据:n≤365
对于30%的数据:日期范围从2010-11-23至2012-12-21
对于70%的数据:日期范围从1900-01-01至9999-12-31
Output Format
输出共n行,每行一个整数,对应于一组数据。
每组数据需要输出在指定日期区间内,共有多少个交易日;区间的开始和结束日期也算在内(如果是交易日的话)。
Sample Input
4
2010-11-18 2010-11-20
2010-01-01 2010-01-01
2010-05-01 2010-05-03
2010-10-01 2010-10-07
Sample Output
2 0 0 0
#include<iostream> #include<cstring> using namespace std; int isyeap(int x){ return x%100!=0 && x%4==0 || x%400==0 ? 1 :0 ; } int dayofmonth[13][2]={ 0,0, 31,31, 28,29, 31,31, 30,30, 31,31, 30,30, 31,31, 31,31, 30,30, 31,31, 30,30, 31,31, }; struct date{ int day; int month; int year; int week; void nextday(){ day++; week++; if(week>7){ week=1; } if(day>dayofmonth[month][isyeap(year)]){ day=1; month++; if(month>12){ month=1; year++; } } } }; int buf[10001][13][32]; int weekday(int y,int m,int d){ if(m==1 || m==2){ m+=12; y--; } return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; } void init(){ date temp; int cnt=0; temp.day=1; temp.month=28; temp.year=1899; temp.week=12; while(temp.year!=10001){ buf[temp.year][temp.month][temp.day]=cnt; temp.nextday(); if(temp.week==6 || temp.week==7) continue; if(temp.month==1 && temp.day==1) continue; if(temp.month==5 && temp.day<=3 ) continue; if(temp.month==10 && temp.day<=7) continue; cnt++; } } int main(){ init(); //freopen("input.txt","r",stdin); int n; cin>>n; string s; getline(cin,s); while(n-->0){ getline(cin,s); int d1,d2,y1,y2,m1,m2; y1=s[3]-'0'+(s[2]-'0')*10+(s[1]-'0')*100+(s[0]-'0')*1000; m1=s[6]-'0'+(s[5]-'0')*10; d1=s[9]-'0'+(s[8]-'0')*10; y2=s[14]-'0'+(s[13]-'0')*10+(s[12]-'0')*100+(s[11]-'0')*1000; m2=s[17]-'0'+(s[16]-'0')*10; d2=s[20]-'0'+(s[19]-'0')*10; if((m1==1 && d1==1) || (m1==5 && d1<=3) || (m1==10 && d1<=7) || weekday(y1,m1,d1)==6 || weekday(y1,m1,d1)==7){ cout<<buf[y2][m2][d2]-buf[y1][m1][d1]<<endl; } else{ cout<<buf[y2][m2][d2]-buf[y1][m1][d1]+1<<endl; } } return 0; }
这是我的代码,觉得没有错,数据也是对的,但提交就是runtime error,很迷。
附上ac的代码:
#include <iostream> #include <stdio.h> using namespace std; int dayOfMonth[][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}}; struct Date { int y,m,d; int leap() { return (y%4==0&&y%100!=0||y%400==0?1:0); } int week() { int Y=y,M=m; if(m==1||m==2) { Y--; M+=12; } int W=(d+M*2+3*(M+1)/5+Y+Y/4-Y/100+Y/400)%7; return W+1; } Date(){} Date(int yy,int mm,int dd){y=yy;m=mm;d=dd;} Date getNext() { Date t(y,m,d); if(d<dayOfMonth[leap()][m]) t.d+=1; else if(m<12) { t.m+=1; t.d=1; } else { t.y+=1; t.m=1; t.d=1; } return t; } bool dealDay() { if(week()==6||week()==7) return false; if(m==1&&d==1||m==5&&d>=1&&d<=3||m==10&&d>=1&&d<=7) return false; return true; } bool isWeekend() { return week()==6||week()==7; } }; bool equals(Date d1,Date d2) { return d1.y==d2.y&&d1.m==d2.m&&d1.d==d2.d; } int ansOfYear(int year) { bool isleap=(year%4==0&&year%100!=0||year%400==0); int res=(isleap?366:365),t1,t2,t3=0,i; t1=104; if(isleap) { if(Date(year,12,30).isWeekend()) t1+=1; if(Date(year,12,31).isWeekend()) t1+=1; } else { if(Date(year,12,31).isWeekend()) t1+=1; } t2=11; if(Date(year,1,1).isWeekend()) t3+=1; for(i=1;i<4;i++) if(Date(year,5,i).isWeekend()) t3+=1; for(i=1;i<8;i++) if(Date(year,10,i).isWeekend()) t3+=1; res=res-t1-t2+t3; return res; } int main() { //freopen("input.txt","r",stdin); int n,res=0,i; Date d1,d2,t; scanf("%d",&n); while(n--) { res=0; scanf("%d-%d-%d %d-%d-%d",&d1.y,&d1.m,&d1.d,&d2.y,&d2.m,&d2.d); if(d2.y-d1.y<=1) { for(t=d1;!equals(t,d2.getNext());t=t.getNext()) if(t.dealDay()) res+=1; } else { for(t=d1;!equals(t,Date(d1.y+1,1,1));t=t.getNext()) if(t.dealDay()) res+=1; for(t=Date(d2.y,1,1);!equals(t,d2.getNext());t=t.getNext()) if(t.dealDay()) res+=1; for(i=d1.y+1;i<d2.y;i++) res+=ansOfYear(i); } printf("%d\n",res); } return 0; }