目录
日期推算
分解因数
日期推算
美国节日__牛客网
思路:
首先,我们要想找到一个月第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;
}