牛客竞赛每日俩题 - Day9

简介: 牛客竞赛每日俩题 - Day9

日期推算

美国节日__牛客网

首先,我们要想找到一个月第N个星期W,一定需要一个参照物,最好的目标当然是这个月的第一天。拿到参照物后,我要能得 到参照物的星期数,然后就能得到结果了。所以这个题有两个难点:判断某个月的1号到底是周几,然后根据这个星期数得到这个月第N个星期W


方法:

1、三部曲求这一年过了几天

int DAYS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool isLeapYear(int y) {
  return y % 400 == 0 || (y % 100 != 0 && y % 4 == 0);
}
int nDays(int y, int m, int d) {
  int n = d;
  for (int i = 0; i < m - 1; i++) {
    n += DAYS[i];
  }
  if (m > 2 && isLeapYear(y)) {
    n++;
  }
  return n;
}

2、 计算从基准日期,到带计算日期过了多少天,然后模取7得到星期几

优化防止爆int:

365*(y-1)%7==(365%7)*((y-1)%7)==1*(y-1)%7==(y-1)%7

int week(int y, int m, int d) {
    int tot=(y - 1) + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + nDays(y, m, d);
  //(y - 1)* 365+中间经历多少闰年*1+最后一年的天数
    int w = tot % 7;
  if (w == 0) {
    w = 7;
  }
  return w;
}

3、通过这个参照点拿到一个月的第N个星期W

那么,我们假设要拿到一个月的第一个周五,我们要怎么做呢?一个很简单的思路就是,先看看这个月的1号是周几,然后往后数就行了,假如1号是周四,那么2号就是第一个周五,假如1号是周六,那么7号就是第一个周五。

那么,怎么拿到这个向后的天数呢?我们发现,如果所求星期数比1号星期数大,那么直接相减后+1就是那一天了,例如1号周三,我要周五,那么(5-3)+1即可求出第一个周五是3号。那么反过来是所求星期数小,例如1号周三,我要周一,那么显然要先把周一看成周八才行。也就是(8-3)+1。第一个周一是6号。但是这样要判断,所以干脆统统都让它加7以后减,减完后的结果再mod一下7,就能得到结果了。也就是:(所求星期数 + 7 - 1号星期数) % 7 + 1。这样我们就拿到了求第一个周几公式。随后,我们只需要在这个公式上,加上7 * (n - 1),即刻求出第n个周几。

而面对某个月的最后一个周几,我们要做的是拿到下个月的第一天然后往回推即可。

// 已知当月1日是星期 w,计算第 n 个星期 e 是几号
int m1(int w, int n, int e) {
  return 1 + (n - 1) * 7 + (7 - w + e) % 7;
}
#include <iostream>
#include <cstdio>
using namespace std;
int DAYS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool isLeapYear(int y) {
  return y % 400 == 0 || (y % 100 != 0 && y % 4 == 0);
}
// 求解 y,m,d 这一年过了多少天
int nDays(int y, int m, int d) {
  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 计算从基准日期,到带计算日期过了多少天。
// 算出这个天数的 MOD 7 的同余数
int week(int y, int m, int d) {
    int tot=(y - 1) + (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400 + nDays(y, m, d);
  int w = tot % 7;
  if (w == 0) {
    w = 7;
  }
  return w;
}
// 已知当月1日是星期 w,计算第 n 个星期 e 是几号
int m1(int w, int n, int e) {
  return 1 + (n - 1) * 7 + (7 - w + e) % 7;
}
int main() {
  int y;
  while (cin >> y) {
    printf("%d-01-01\n", y);
    int w;
    w = week(y, 1, 1);
    printf("%d-01-%02d\n", y, m1(w, 3, 1));
    w = week(y, 2, 1);
    printf("%d-02-%02d\n", y, m1(w, 3, 1));
    w = week(y, 6, 1);
    int d = (w == 1 ? 7 : w - 1);
    printf("%d-05-%02d\n", y, 32-d);
    printf("%d-07-04\n", y);
    w = week(y, 9, 1);
    printf("%d-09-%02d\n", y, m1(w, 1, 1));
    w = week(y, 11, 1);
    printf("%d-11-%02d\n", y, m1(w, 4, 4));
    printf("%d-12-25\n\n", y);
  }
}

分解因数

分解因数__牛客网

16
16 = 2 * 2 * 2 * 2
345
345 = 3 * 5 * 23
44
44 = 2 * 2 * 11
90
90 = 2 * 3 * 3 * 5

对因子分解最简写法

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        printf("%d = ",n);
        for(int i=2;i<=sqrt(n);i++)//注意n是会改变的,所以遍历范围远小于n的算术平方根
        {
            while(n!=i)
            {
                if(n%i==0)
                {
                    printf("%d * ",i);
                    n/=i;
                }
                else break;
            }
        }
        cout<<n<<endl;
    }
    return 0;
}
相关文章
|
6月前
|
存储
每日一题——leetcode682.棒球比赛
每日一题——leetcode682.棒球比赛
|
容器
牛客竞赛每日俩题 - Day10
牛客竞赛每日俩题 - Day10
|
算法
牛客竞赛每日俩题 - Day14
牛客竞赛每日俩题 - Day14
|
测试技术 数据库
牛客竞赛每日俩题 - Day12
牛客竞赛每日俩题 - Day12
|
机器学习/深度学习 存储 自然语言处理
牛客竞赛每日俩题 - 动态规划1
牛客竞赛每日俩题 - 动态规划1
|
人工智能 BI
牛客竞赛每日俩题 - Day4
牛客竞赛每日俩题 - Day4
102 0
牛客竞赛每日俩题 - Day4
|
存储 测试技术
牛客竞赛每日俩题 - Day13
牛客竞赛每日俩题 - Day13
牛客竞赛每日俩题 - Day3
牛客竞赛每日俩题 - Day3
|
机器学习/深度学习
牛客竞赛每日俩题 - Day8
牛客竞赛每日俩题 - Day8