• A Daily Topic # 6 星期几(模拟)


    A Daily Topic # 6

    星期几

    已知 1 年 1 月 1 日是星期一。

    现在给定一个日期,请你判断是星期几。

    注意闰年的 2 月有 29 天。

    满足下面条件之一的是闰年:

    1. 年份是 4 的整数倍,而且不是 100 的整数倍;
    2. 年份是 400 的整数倍。

    输入格式

    输入包含多组测试数据。

    每组数据占一行,包含一个整数 d 表示日,一个字符串 m 表示月,一个整数 y 表示年。

    月份 1∼12,依次如下所示:

    January, February, March, April, May, June, July, August, September, October, November, December
    

    输出格式

    每组数据输出一行结果,输出一个字符串表示给定日期是星期几。

    周一至周日依次如下所示:

    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
    

    数据范围

    1000≤y≤3000,
    给定日期保证合法。
    每个输入最多包含 100 组数据。

    输入样例:

    9 October 2001
    14 October 2001
    

    输出样例:

    Tuesday
    Sunday
    

    +++

    思路:

    365 * 3000 * 1000 = 1,095,000,000

    虽然数据量大,但是代码常数小,直接暴力模拟也可以过掉。

    下面是优化。

    优化:

    我们看y的范围是[1000, 3000],所以知道1000年以前的循环每次询问都会进行一遍,是重复的行为,这就导致速度很慢。所以我们不妨通过一遍模拟算出1000年1月1日是周几(通过模拟可以得到是周三),然后每次询问的时候我们从1000年1月1日开始循环,速度可以快近一半。

    具体操作:(有很多种实现方式)

    我们知道1000年1月1日是周三,所以我们不妨把他看成”新的周一“,周四看成”新的周二“,所以我们的week_name数组就是这样的:

    string week_name[7] ={"Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday"};

    然后将while循环中的 i 初值赋为1000,就可以了。代码如下:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <unordered_map>
    
    using namespace std;
    
    int d, y, m;
    string str;
    int months[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    unordered_map<string, int> month_name = 
    {
        {"January", 1},
        {"February", 2},
        {"March", 3},
        {"April", 4},
        {"May", 5},
        {"June", 6},
        {"July", 7},
        {"August", 8},
        {"September", 9},
        {"October", 10},
        {"November", 11},
        {"December", 12},
    };
    string week_name[7] ={"Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday"};//新的week数组
    
    int is_leap(int year)
    {
        return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    }
    
    int get_days(int year, int month)
    {
        int s = months[month];
        if (month == 2) return s + is_leap(year);
        return s;
    }
    
    int main()
    {
        while (cin >> d >> str >> y)
        {
            int m = month_name[str];
            int i = 1000, j = 1, k = 1;//从1000年1月1日开始模拟
            int days = 0;
            
            //从第一天开始模拟
            while (i < y || j < m || k < d)
            {
                days ++ ;
                k ++ ;
                if (k > get_days(i, j))
                {
                    k = 1;
                    j ++ ;
                    
                    if (j > 12)
                    {
                        j = 1;
                        i ++ ;
                    }
                }
            }
            
        cout << week_name[days % 7] << endl;
        }
        
        return 0;
    }
    
  • 相关阅读:
    Vue.js实现的计算器功能完整示例
    vue实现简易计算器
    Vuex中mutations与actions的区别详解
    两个子组件之间的传值
    JS操作元素节点(非常详细)
    js包装类
    Vue Router 的params和query传参的使用和区别(详尽)
    初步了解生命周期
    简单介绍一下Progressive Web App(PWA)
    webpack学习笔记(阮一峰教程demo)
  • 原文地址:https://www.cnblogs.com/scl0725/p/14773583.html
Copyright © 2020-2023  润新知