【Java版oj】day31美国节日、分解因数

目录

 一、美国节日

(1)原题再现

(2)问题分析

(3)完整代码

 二、分解因数

(1)原题再现

(2)问题分析

(3)完整代码

三、DFS深度优先列举所有可能的情况


 一、美国节日

(1)原题再现

美国节日__牛客网

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

输入描述

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

输出描述

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

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

示例

2014

201

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

(2)问题分析

    根据蔡勒公式计算星期数。(以下摘自百度百科)

(或者是:

若要计算的日期是在1582年10月4日或之前,公式则为

以1582年10月4日为例:

1582年10月4日后:w = (d + 1+ 2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;

1582年10月4日前:w = (d+1+2*m+3*(m+1)/5+y+y/4+5) % 7;

或者1752年9月3日为例

1752年9月3日后:w = (d + 2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7;(这个公式应该是跟正常的相差1的,也就是算出来相差了一天)

1752年9月3日前:w = (d+2*m+3*(m+1)/5+y+y/4+5) % 7;

注:罗马教皇决定在1582年10月4日后使用格利戈里历法;而英国则是在1752年9月3日后才接受使用格利戈里历法。

注意:

当年的1,2月要当成上一年的13,14月进行计算

符号意义:

w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六

c:世纪(注:一般情况下,在公式中取值为已经过的世纪数,也就是年份除以一百的结果,而非正在进行的世纪,也就是现在常用的年份除以一百加一;不过如果年份是公元前的年份且非整百数的话,c应该等于所在世纪的编号,如公元前253年,是公元前3世纪,c就等于-3)

y:年(一般情况下是后两位数,如果是公元前的年份且非整百数,y应该等于cMOD100+100)

m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算)

d:日

[ ]代表取整,即只要整数部分。

下面以中华人民共和国成立100周年纪念日那天(2049年10月1日)来计算是星期几,过程如下:

w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

=49+[49/4]+[20/4]-2×20+[26×(10+1)/10]+1-1

=49+[12.25]+5-40+[28.6]

=49+12+5-40+28

=54 (除以7余5)

即2049年10月1日(100周年国庆)是星期五。

再比如计算2006年4月4日,过程如下:

w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

=6+[6/4]+[20/4]-2*20+[26*(4+1)/10]+4-1

=-12 (除以7余5,注意对负数的取模运算!实际上应该是星期二而不是星期五)

w=(-12%7+7)%7=2;

然后求这年这月第一天是星期几,这是为了求这年这月这日是星期几

(3)完整代码

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

/*
 * 分解因数
 */
//超时但是结果都对
public class DecomposingNumbers {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            int num = sc.nextInt();
   
            List <Integer>list = new LinkedList<>();
            for (int i = 1; i <= num; i++) { //1~num有多少个质数
                int temp = isFactor(i);
                if (temp != -1) { //是质数加入列表
                    list.add(temp);
                }
            }

            List<Integer>one = new LinkedList<>();
            List<List<Integer>>res = new LinkedList<>();
            DFS(0, num, 1, list, one, res);
            System.out.print(num + "=");
            for (int i = 0; i < res.size(); i++) {
                for (int j = 0; j < res.get(i).size(); j++) {
                    if (j == res.get(i).size() - 1) {
                        System.out.print(res.get(i).get(j)+" ");
                    } else {
                        System.out.print(res.get(i).get(j) + "*");
                    }
                }
            }
        }
    }
    public static void DFS(int index, int num, int mulRes, List<Integer>list,List<Integer> one, List<List<Integer>> res) {
        //num目标值,list所有比num小的质数集合,one存放一种正确的组合,res结果集合;每一种正确的组合都放进结果集,mulRes当前的数,index下标位置
        if (mulRes > num) {//当前值大于目标值
            return;
        }
        if (mulRes == num) {//当前值等于目标值,表示这个组合正确,是我们想要的
            List<Integer> temp = new
            LinkedList<>(); //临时变量,将一种组合放入结果集
            for (int i = 0; i < one.size(); i++) {
                temp.add(one.get(i));
            }
            res.add(temp);
            return;
        }
        for (int i = index; i < list.size(); i++) {
            if (mulRes > num) {
                continue;//如果当前值大于目标值就下一个,但是本题按顺序排的不会出现这种情况,可以不写
            }
            one.add(list.get(i));
            DFS(i, num, mulRes * list.get(i), list, one, res);
            one.remove(one.size() -
                       1); //回溯,当前值如果大于等于就要回到上一步,然后不合适的质数删去走下一步
        }
    }
    public static int isFactor(int num) {//判断某个数是否为质数
        if (num == 1) {
            return -1;
        }
        if (num == 2) {
            return 2;
        }
        for (int i = 2; i < num; i++) {
            if (num % i == 0) {
                return -1;//不是返回-1
            }
        }
        return num;//是返回该值
    }
}

 二、分解因数

(1)原题再现

分解因数__牛客网
        所谓因子分解,就是把给定的正整数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

(2)问题分析

       我首先想到的DFS深度优先算法,把所有组合情况列举出来,但是会造成超时错误。我会把DFS的代码放到文末,有兴趣的同学可以感受一下深度优先的魅力。

        这道题和昨天的因子个数是一样,用质数去试除。例如30能被2整除,那就拿商继续除以2,除不尽就换3,一直到除到质数为止。注意输出格式。

(3)完整代码

import java.util.Scanner;

/*
 * 分解因数
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            int num = sc.nextInt();
            System.out.print(num + " = ");
            for (int i = 2; i <= num; i++) {
                while (num % i == 0) {
                    if (num == i) {
                        System.out.println(i);
                    } else {
                        System.out.print(i + " * ");
                    }
                    num /= i;
                }
            }
        }
    }
}

​​

三、DFS深度优先列举所有可能的情况

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小熊爱吃软糖吖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值