Description
二哥想知道在一段时期内,一共有多少个交易日。期货交易日的限定如下:
周六、周日不能交易
元旦期间(1月1日)不能交易
五一劳动节期间(5月1日至3日)不能交易
十一国庆节期间(10月1日至7日)不能交易
没有在上述要求中提到的日期均可交易
Input Format
第一行有一个整数n,表示一共有n组数据。
每组数据都有一行,是两个用空格分开的日期,分别为开始日期和结束日期。日期格式为YYYY-MM-DD(比如2010-11-11);数据保证开始日期不晚于结束日期。
对于所有数据:n≤365n≤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
思路一:将每年按节日划分为三段XXXX-01-01至XXXX-04-30,XXXX-05-01至XXXX-09-01,XXXX-10-01至XXXX-12-31分别计算天数,再对起始日期进行判断,如果是交易日就加回来。
#include
#include
int dayos[8099];
int get_doy(int yyyy,int mm,int dd)
{
int isLeap = (!(yyyy % 4) && (yyyy % 100)) || !(yyyy % 400);
int doy = 0,moy;
int mds[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
for(moy = 0; moy < mm - 1; moy++){
doy += mds[moy]+((1==moy&&isLeap)?1:0);
}
doy += dd;
return doy;
}
int judge(int dayo, int emm, int edd, int toy){
if( 1 == emm && 1 == edd ){
return 0;
}
if( 5 == emm && 1 <= edd && 3 >= edd){
return 0;
}
if( 10 == emm && 1 <= edd && 7 >= edd){
return 0;
}
if((dayo+toy-1) % 7 > 4){
return 0;
}
return 1;
}
int main()
{
int n;
int syyyy,smm,sdd,eyyyy,emm,edd;
int tyyyy;
int foy,toy,soy,eoy;
int isLeap = 0, dayo = 0;
int daycnt = 0,i,tempcnt,daystart,leftdays,alldays;
int semap[3][4]={{1,1,4,30},{5,3,9,30},{10,7,12,31}};
dayos[0] = 0;
for(i = 0;i < 8099;i++){
isLeap = (!((i+1900) % 4) && ((i+1900) % 100)) || !((i+1900) % 400);
dayos[i+1] = (dayos[i] + (isLeap?366:365))%7;
}
scanf("%d", &n);
while(n--){
scanf("%d-%d-%d %d-%d-%d",&syyyy,&smm,&sdd,&eyyyy,&emm,&edd);
daycnt = 0;
foy = get_doy(syyyy,smm,sdd);
toy = get_doy(eyyyy,emm,edd);
for(tyyyy=syyyy;tyyyy <= eyyyy;tyyyy++){
dayo=dayos[tyyyy-1900];
for(i = 0; i < 3; i++){
soy = get_doy(tyyyy,semap[i][0],semap[i][1]);
eoy = get_doy(tyyyy,semap[i][2],semap[i][3]);
if(tyyyy == syyyy)
{
if(foy > eoy){
continue;
}
else if(foy > soy && foy <= eoy)
{
soy = foy;
}
}
if(tyyyy == eyyyy)
{
if(toy < soy){
continue;
}
else if(toy >= soy && toy < eoy){
eoy = toy;
}
}
tempcnt = eoy - soy;
daystart = (dayo + soy)%7;
alldays = daystart + tempcnt;
leftdays = alldays % 7;
tempcnt = (alldays / 7) * 5 - (daystart > 4 ? 5:daystart) + (leftdays > 4 ? 5:leftdays);
daycnt += tempcnt;
}
}
//Judge if toy is weekday
daycnt += judge(dayos[syyyy-1900],smm,sdd,foy);
printf("%d\n",daycnt);
}
return 0;
}
这种方法分段内容太多所以效率较低:时间531ms 空间:9344kb
思路二:整段计算前后天数再将所有节日判断后剔除。
// 暂略