【牛客网】美国节日与因式分解

目录

一、编程题

1.美国节日

2.因式分解


 

一、编程题

1.美国节日

链接:美国节日__牛客网 (nowcoder.com)

和中国的节日不同,美国的节假日通常是选择某个月的第几个星期几这种形式,因此每一年的放假日期都不相同。具体规则如下:
* 1月1日:元旦
* 1月的第三个星期一:马丁·路德·金纪念日
* 2月的第三个星期一:总统节
* 5月的最后一个星期一:阵亡将士纪念日
* 7月4日:美国国庆
* 9月的第一个星期一:劳动节
* 11月的第四个星期四:感恩节
* 12月25日:圣诞节
现在给出一个年份,请你帮忙生成当年节日的日期。

输入描述:

输入包含多组数据,每组数据包含一个正整数year(2000≤year≤9999)。

输出描述:

对应每一组数据,以“YYYY-MM-DD”格式输出当年所有的节日日期,每个日期占一行。

每组数据之后输出一个空行作为分隔。

示例1

输入

2014

2013:

输出

2014-01-01

2014-01-20

2014-02-17

2014-05-26

2014-07-04

2014-09-01

2014-11-27

2014-12-25

2013-01-01

2013-01-21

2013-02-18

2013-05-27

2013-07-04

2013-09-02

2013-11-28

2013-12-25

🔎思路分析:

fc304326a7da4ac585db80459eac24b5.png

✨按照这个思路,我们如何让得知某个年月日是星期几

91ab99c769c64d028793af669477e65a.png

🌈此时把问题转化为求解:中间经历多少闰年 和 最后一年的天数 

24617769459b4374a3935e0cba811705.png

 1️⃣以上解析实际上是求出 给定y、m、d,如何得知该天是星球几

 eb4b9117327847dfa1791e897813568d.png

 2️⃣已知星球几,求具体是哪天:

5cca8c5cb250412a82c9a016dcc0239a.png

fefb6560106642f8a1a14275af8b97ae.png 总结:

9d1cd64f14b64bb1a51f3e93047bfc1c.png

public class Main {
    private static boolean isLeapYear(int y) {
        return (y % 400 == 0) || (y % 4 == 0 && y % 100 != 0);
    }
    private static final int[] DAYS = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 给定 y,m,d,返回这年过了多少天了
    private static int nDays(int y, int m, int d) {
// m: 12
// [0, 10]
        int n = d;
        for (int i = 0; i < m - 1; i++) {
            n += DAYS[i];
        }
        if (m > 2 && isLeapYear(y)) {
            n++;
        }
        return n;
    }
// 传入 y,m,d,找到从公元前 1 年12月31日开始过了多久了。求出它的 MOD 7 的同余数
    private static int diff(int y, int m, int d) {
        return (y - 1) + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + nDays(y, m, d);
    }
// 根据 y,m,d 求出星期几
    private static int week(int y, int m, int d) {
        int w = diff(y, m, d) % 7;
        if (w == 0) {
            w = 7;
        }
        return w;
    }
// 根据 1 日星期 w,求第 n 个星期 e 是几号
    private static int m1(int w, int n, int e) {
        return 1 + (n - 1) * 7 + (7 - w + e) % 7;
    }
// 根据 6月1日星期 w,求5月的最后一个星期一
    private static int m2(int w) {
        int d = (w == 1 ? 7 : w - 1);
        return 32 - d;
    }
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        while (s.hasNextInt()) {
            int y = s.nextInt();
            System.out.printf("%d-01-01\n", y);
            int w;
            w = week(y, 1, 1);
            System.out.printf("%d-01-%02d\n", y, m1(w, 3, 1));
            w = week(y, 2, 1);
            System.out.printf("%d-02-%02d\n", y, m1(w, 3, 1));
            w = week(y, 6, 1);
            System.out.printf("%d-05-%02d\n", y, m2(w));
            System.out.printf("%d-07-04\n", y);
            w = week(y, 9, 1);
            System.out.printf("%d-09-%02d\n", y, m1(w, 1, 1));
            w = week(y, 11, 1);
            System.out.printf("%d-11-%02d\n", y, m1(w, 4, 4));
            System.out.printf("%d-12-25\n", y);
            System.out.println();
        }
    }
}

2.因式分解

链接:分解因数__牛客网 (nowcoder.com)

所谓因子分解,就是把给定的正整数a,分解成若干个素数的乘积,即 a = a1 × a2 × a3 × ... × an,并且 1 < a1 ≤ a2 ≤ a3 ≤ ... ≤ an。其中a1、a2、...、an均为素数。 先给出一个整数a,请输出分解后的因子。
输入描述:

输入包含多组数据,每组数据包含一个正整数a(2≤a≤1000000)。

输出描述:

对应每组数据,以“a = a1 * a2 * a3...”的形式输出因式分解后的结果。
示例1

输入

10

8

输出

10 = 2 * 5

18 = 2 * 3 * 3

🔎思路分析:

b269d79e42594f2cbfcdc0b9a74f03d9.png

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int a = scanner.nextInt();
            List<String> factors = factorization(a);
            System.out.printf("%d = %s\n", a, String.join(" * ", factors));
        }
    }

    private static List<String> factorization(int a) {
        List<String> ans = new ArrayList<>();

        for (int i = 2; a > 1 && i * i <= a; i++) {
            while (a % i == 0) {
                ans.add(String.valueOf(i));
                a = a / i;
            }
        }
        if (a > 1) {
            ans.add(String.valueOf(a));
        }
        return ans;
    }
}

 

 

 

 

 

  • 113
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 96
    评论
评论 96
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗小温

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值