zoukankan      html  css  js  c++  java
  • 1008. 二哥买期货

    http://acm.sjtu.edu.cn/OnlineJudge/problem/1008

    对起始年份和结束年份,可以对每一天单独判断;

    对中间的每个整年,周末总的天数分为两部分:

    1. 每个整年恰有完整的52个周,所以至少有 2*52 天是周末;

    2. 闰年时,366%7 = 2,需要判断12-31和12-30是否为周末即可,平年需要判断12-31是否为周末;

    对中间的每个整年,都有11天假日,注意周末与假日重合的情况。

    这道题麻烦之处在于星期的计算和周末与假日重合时的处理。

    星期的计算公式:

    1 int getweek(int y, int m, int d)
    2 {
    3     if (m==1 || m==2) m += 12, y -= 1;
    4     return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1) % 7;
    5 }

    单独对每个假日进行判断,就避免了周末与假日重合时重复计算:

    int holidays[11][2] = {{1,1}, {5,1}, {5,2}, {5,3}, {10,1}, {10,2}, {10,3}, {10,4}, {10,5}, {10,6}, {10,7}};
    
    for (int j = 0; j < 11; ++j) {
        if (isWeekend(curYear, holidays[j][0], holidays[j][1]))
            ++ans;
    }

    (枚举的做法会超时,不过需要对拍时很有用。)

      1 # include <stdio.h>
      2 
      3 int holidays[11][2] = {{1,1}, {5,1}, {5,2}, {5,3}, {10,1}, {10,2}, {10,3}, {10,4}, {10,5}, {10,6}, {10,7}};
      4 
      5 int getweek(int y, int m, int d)
      6 {
      7     if (m==1 || m==2) m += 12, y -= 1;
      8     return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1) % 7;
      9 }
     10 bool isWeekend(int y, int m, int d)
     11 {
     12     int w = getweek(y, m, d);
     13     return (w==0 || w==6);
     14 }
     15 
     16 const int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
     17 bool isLeapYear(int year) { return year%400==0 || (year%4==0 && year%100!=0); }
     18 
     19 void getdate(int &y, int &m, int &d)
     20 {
     21     char s[20];
     22     scanf("%s", s);
     23     y = (s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0');
     24     m = (s[5]-'0')*10+(s[6]-'0');
     25     d = (s[8]-'0')*10+(s[9]-'0');
     26 }
     27 
     28 bool isHoliday(int m, int d)
     29 {
     30     for (int i = 0; i < 11; ++i) {
     31         if (holidays[i][0] == m && holidays[i][1] == d) return true;
     32     }
     33     return false;
     34 }
     35 
     36 bool isEndOfMonth(int y, int m, int d)
     37 {
     38     if (m != 2 && d == days[m]) return true;
     39     else if (m==2) {
     40         if (isLeapYear(y)) return d == 29;
     41         else return d == 28;
     42     }
     43     return false;
     44 }
     45 
     46 int cal(int year, int m, int d, int mm, int dd)
     47 {
     48     int cnt = 0;
     49     for (int i = m, j = d; i < mm || (i==mm && j<=dd); ) {
     50         if (!isWeekend(year, i, j) && !isHoliday(i, j)) {
     51             ++cnt;
     52         }
     53         if (isEndOfMonth(year, i, j)) {
     54             ++i, j = 1;
     55         } else {
     56             ++j;
     57         }
     58     }
     59     return cnt;
     60 }
     61 
     62 void solve(void)
     63 {
     64     int n;
     65     int y1, m1, d1;
     66     int y2, m2, d2;
     67     scanf("%d", &n);
     68     while (n--) {
     69         getdate(y1, m1, d1);
     70         getdate(y2, m2, d2);
     71 
     72         int ans = 0;
     73 
     74         if (y1 == y2) {
     75             ans = cal(y1, m1, d1, m2, d2);
     76         } else {
     77             ans = cal(y1, m1, d1, 12, 31) + cal(y2, 1, 1, m2, d2);
     78             for (int i = y1+1; i < y2; ++i) {
     79                 if (isLeapYear(i)) {
     80                     ans += 366-52*2;
     81                     if (isWeekend(i, 12, 30)) --ans;
     82                     if (isWeekend(i, 12, 31)) --ans;
     83                 } else {
     84                     ans += 365-52*2;
     85                     if (isWeekend(i, 12, 31)) --ans;
     86                 }
     87                 ans -= 11;
     88                 for (int j = 0; j < 11; ++j) {
     89                     if (isWeekend(i, holidays[j][0], holidays[j][1]))
     90                         ++ans;
     91                 }
     92             }
     93         }
     94 
     95         printf("%d
    ", ans);
     96     }
     97 }
     98 
     99 int main()
    100 {
    101     solve();
    102 
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    POJ NOI MATH-7650 不定方程求解
    POJ NOI MATH-7656 李白的酒
    POJ NOI MATH-7654 等差数列末项计算
    POJ NOI MATH-7827 质数的和与积
    POJ NOI MATH-7830 求小数的某一位
    POJ NOI MATH-7833 幂的末尾
    POJ NOI MATH-7829 神奇序列求和
    POJ NOI MATH-7826 分苹果
    UVALive5661 UVA668 ZOJ2037 Parliament
    POJ1032 Parliament
  • 原文地址:https://www.cnblogs.com/txd0u/p/3354357.html
Copyright © 2011-2022 走看看