试题 算法提高 Intersecting Dates

问题:
研究组正在开发一个计算机程序,这个程序会从一个服务获得历史股票市场价格数据。而这个服务每提供一天的股市数据,都要收取一个固定的费用。这个研究组检查了过去请求的价格数据,发现有着大量的重复,也就浪费了不少的研究经费。所以新的程序需要维护一个表来保存研究组成员曾经请求过的所有价格数据。当需要一段新的价格数据时,只有曾经没有请求过的会从服务获得,从而减少研究开销。

你的任务是完成一个程序来判断是否需要从服务请求新的价格数据。程序的输入包括所有过去请求过的价格数据的日期区间,和现在需要的日期区间。这个程序需要输出必须从服务获得的数据的日期区间。

大思路:把距离1700年1月1日的天数全部记录下来,就是data to day,
然后再把符合条件的天数转换成日期,就是day to date。

代码

#include<stdio.h>
#include <iostream>
#include<string.h>

int Month_days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
int fill_arry[147000] = {0};

int IsLeapYear(int year);
int Date_to_Day(int date);
void Fill_days(int date1, int date2, int flii_number);
void Day_to_Date(int day);

int main()
{
 int NX, NR;
 int search_begin, search_end;
 int a[100] = { 0 }, b[100] = { 0 };
 int i = 0;
 int k = 0;
 int flag = 0;
 int cases = 0;
 while (scanf("%d %d", &NX, &NR) && (NX + NR))
 {
  memset(fill_arry, 0, sizeof(fill_arry));
  for (i = 0; i < NX; i++)
  {
   scanf("%d %d", &a[i], &b[i]);
  }
  for (i = 0; i < NR; i++)
  {
   scanf("%d %d", &search_begin, &search_end);
   Fill_days(search_begin, search_end, 1);    //要获得的日期填1;
  }
  for (i = 0; i < NX; i++)
  {
   Fill_days(a[i], b[i], 2);          //已获得的日期天2;
  }
  flag = 1;
  printf("Case %d:\n", ++cases);
  for (i = 0; i < 147000; i++)
  {
   if (fill_arry[i] == 1)
   {
    flag = 0;
    printf("    ");
    Day_to_Date(i);
    if (fill_arry[i + 1] == 2 || fill_arry[i+1]==0)
    {
     printf("\n");
    }
    else
    {
     printf(" to ");
     for (k = i; fill_arry[k] == 1; k++);
     Day_to_Date(k - 1);
     printf("\n");
     i = k;
    }
   }
  }
  if (flag)
  {
   printf("    No additional quotes are required.\n");
  }
  printf("\n");
 }
}
int IsLeapYear(int year)
{
 return (year % 400==0) || (year % 4 == 0 && year % 100 != 0);
}
int Date_to_Day(int date)
{
 int Sum_Day = 0;
 int x = date / 10000;
 for (int i = 1700; i<x; i++)
 {
  Sum_Day += IsLeapYear(i)+365;
 }
 x = date % 10000 / 100;
 for (int i = 1; i < x; i++)
 {
  Sum_Day += Month_days[i]+(i == 2 && IsLeapYear(date / 10000));
 }
 x = date % 100;
 return Sum_Day + x;
 }

void Fill_days(int date1, int date2, int flii_number)
{
 int day_start = Date_to_Day(date1);
 int day_end = Date_to_Day(date2);
 for (int i = day_start; i <= day_end; i++)
 {
  fill_arry[i] = flii_number;
 }
}


void Day_to_Date(int day)
{
 int year = 1700,Month = 1;
 for (year = 1700; day>365+IsLeapYear(year); year++)
 {
  day -= 365 + IsLeapYear(year);
 }
 for ( Month = 0; day >Month_days[Month]+(Month==2&&IsLeapYear(year)) ; Month++)
 {
  day -= Month_days[Month]+(Month == 2 && IsLeapYear(year));
 }
 printf("%d/%d/%d", Month, day, year);
}





















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值