蓝桥杯 试题 算法提高 Intersecting Dates

资源限制
时间限制:2.0s   内存限制:256.0MB
问题描述
  研究组正在开发一个计算机程序,这个程序会从一个服务获得历史股票市场价格数据。而这个服务每提供一天的股市数据,都要收取一个固定的费用。这个研究组检查了过去请求的价格数据,发现有着大量的重复,也就浪费了不少的研究经费。所以新的程序需要维护一个表来保存研究组成员曾经请求过的所有价格数据。当需要一段新的价格数据时,只有曾经没有请求过的会从服务获得,从而减少研究开销。
  你的任务是完成一个程序来判断是否需要从服务请求新的价格数据。程序的输入包括所有过去请求过的价格数据的日期区间,和现在需要的日期区间。这个程序需要输出必须从服务获得的数据的日期区间。
输入格式
  有多组测试数据。每组测试数据以两个非负整数 NX 和 NR 开始,(0 <= NX, NR <= 100)。NX 是已获取过的日期区间数,NR 是现在需要的日期区间数。接下去的输入是 NX + NR 对日期。每对日期的第一个日期都一定小于等于第二个日期。前面的 NX 对日期表示已获取过的日期区间,后 NR 对表示现在需要的日期区间。
  最后一组测试数据后,以两个零终结输入。
  每个输入日期都会以 YYYYMMDD 的形式给定。YYYY 是年份(1700 到 2100),MM 代表月份(01 到 12),而 DD 表示日(在给定的年份、月份允许的范围内)。月份 04、06、09、11 有 30 天,而 01、03、05、07、08、10、12 有 31 天,除了闰年,02 月有 28 天,而闰年则为 29 天。如果年份能被 4 整除并且不是一个世纪年(100 的倍数),或者是 400 的倍数时,可以判定这年是闰年。
输出格式
  对于每组测试数据,首先显示测试数据编号(1,2,...),紧接着是一个表,内容是必须从服务获得数据的日期区间,每行一个。以下面样例显示的美国日期格式输出。当没有价格数据需要从服务获取时明确地说明(如样例)。如果两个日期区间是连续的或者重叠的,将它们合并为一个。如果一个日期区间里只有一天,只需将其显示出来,而不是显示包括两个相同日期的日期区间。以日期顺序显示日期区间,从最早的日期开始。
样例输入
1 1
19900101 19901231
19901201 20000131
0 3
19720101 19720131
19720201 19720228
19720301 19720301
1 1
20010101 20011231
20010515 20010901
0 0
样例输出
Case 1:
____1/1/1991 to 1/31/2000

Case 2:
____1/1/1972 to 2/28/1972
____3/1/1972

Case 3:
____No additional quotes are required.

(为防止被格式化掉我用 `_` 代表空格,即实际输出应使用四个空格)
数据规模和约定
  0 <= NX, NR <= 100

  年份范围为 1700 年到 2100 年。

  测试数据组数 <= 100
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
char c[147000];
int cases,st[101],ed[101];
int leap(int y){
    return y%400==0||y%4==0&&y%100;
}

void get_date(int day){
    int y,m;
    for(y=1700;day>365+leap(y);y++)
        day-=(365+leap(y));
    for(m=1;day>days[m]+(m==2&&leap(y));m++){
        day-=days[m]+(m==2&&leap(y));
    }    
    printf("%d/%d/%d",m,day,y);
}
int f(int x){
    int i,tmp,sum;
    tmp = x/10000;
    sum = 0;
    for(i = 1700;i<tmp;i++){
        sum+=365;
        if(leap(i))
            sum++;
    }
    tmp = x%10000/100;
    for(i=1;i<tmp;i++){
        sum+=days[i];
        if(i==2&&leap(x/10000))
            sum++;
    }
    return sum+x%100;
}
void fill(int a,int b,int x){
    int fa,fb;
    fa = f(a);
    fb = f(b);
    memset(&c[fa],x,fb-fa+1);
}
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)&&n+m){
        if(cases)
            cout<<endl;
        memset(c,0,sizeof(c));
        int a,b;
        for(int i=0;i<n;i++)
            scanf("%d%d",&st[i],&ed[i]);
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            fill(a,b,2);
        }
        for(int i=0;i<n;i++)
            fill(st[i],ed[i],1);
        printf("Case %d:\n",++cases);
        bool flag=true;
        for(int i=0;i<147000;i++){
            if(c[i]>1){
                flag = false;
                cout<<"    ";
                get_date(i);
                if(c[i+1]<2){
                    cout<<endl;
                }
                else{
                    printf(" to ");
                    int j;
                    for(j=i;c[j]>1;j++);
                    get_date(j-1);
                    cout<<endl;
                    i = j;
                }
            }
        }
        if(flag)
            cout<<"    No additional quotes are required."<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lusiqi/p/12521498.html