UESTC 1299 Date 预处理、打表、找周期、前缀和
来源:互联网 发布:服务器php环境配置 编辑:程序博客网 时间:2024/05/29 02:47
Date
Time Limit: 2000/1000MS (Java/Others) Memory Limit: 131072/131072KB (Java/Others)
A special day is the day that is
In February
Now, given a time interval, how many special days in total?
Input
The first line is an integer
Then
Each line contains two dates year month day
.
Output
For each query, output the answer in one line.
Sample input and output
22016 2 1 2016 2 72016 2 1 2022 6 1
777
Hint
Note that the answer may be large, please using long long
Source
The 14th UESTC Programming Contest Preliminary
My Solution
too young too simple,当时初赛的时候,觉得必定会有一个周期,然后想不出该是怎样的周期,就不能猜几个试试看吗,先猜最特殊的呗
400 1200什么的,和闰年有关的数字
365 % 7 == 1
366 % 7 == 2
400年多出来的天数刚好可以被7整除,所以可得400年为一个周期
当时比赛的时候,笔者强行在万年历里面找规律,发现周期可能为28,确实28年多出了的也可以被7整除,但不够,不完整
赛后知道是400年为一个最小正周期,还是WA了3发, 主要是具体处理周期、周期总specialdays、输出时候的处理,
if(cnt[y1][m1]){
if(d1 > 7) cout<<sum2-sum1<<endl; //如果已经 d1 > 7了则可以直接减去
else cout<<sum2-sum1+1<<endl; //1 2 3 4 5 6 7 都是 + 1 因为当天是special day 但被减去了,要加上1
}
else cout<<sum2-sum1<<endl; //那个月没有special days ,直接减去即可
#include <iostream>#include <cstdio>#include <cstring>using namespace std;bool cnt[401][13];int date[13];bool runnian(int yr){ if(yr % 400 != 0) {if(yr % 100 == 0) return false;else if(yr % 4 != 0) return false; else return true;} else return true;}int main(){ #ifdef LOCAL freopen("a.txt", "r", stdin); #endif // LOCAL date[1]=31; date[2]=28; date[3]=31; date[4]=30; date[5]=31; date[6]=30; date[7]=31; date[8]=31; date[9]=30; date[10]=31; date[11]=30; date[12]=31; int thedays; long long specialday = 14; memset(cnt, 0, sizeof cnt); cnt[0][2]=1; cnt[0][8]=1; thedays = 335; for(int i = 2017; i < 2016+400; i++){ //这个周期必须刚好,不然在算一个周期总共多少个 special days 的时候会出问题 for(int j = 1; j <= 12; j++){ thedays += date[j]; if(j == 2) thedays += runnian(i); //if return true then add 1, else add 0 // only if j == 2, we judge the runnian() if(thedays % 7 == 0) {/*it is wrong cnt[i-2016][j+1 > 12 ? 1 : j+1] = true;*/ if(j != 12) cnt[i-2016][j + 1] = true; else cnt[i-2016+1][1] = true; specialday += 7; if(i == 2415 && j == 12) specialday -= 7; } } } //从2016 1 1 到 2415 12 1/* 验证一下对不对 cout<<cnt[1][5]<<endl; cout<<cnt[2][1]<<endl; cout<<cnt[2][10]<<endl; cout<<cnt[3][4]<<endl; cout<<cnt[3][7]<<endl; cout<<cnt[4][6]<<endl; cout<<cnt[5][2]<<endl; cout<<cnt[5][3]<<endl; cout<<cnt[5][11]<<endl;*/ int T,y1,y2,m1,m2,d1,d2; long long sum1,sum2; scanf("%d", &T); while(T--){ sum1 = 0;sum2 = 0; scanf("%d%d%d%d%d%d", &y1, &m1, &d1, &y2, &m2, &d2); long long t = (y1-2016)/400;sum1 += t*specialday;y1 = (y1-2016) % 400; for(int i = 0; i < y1; i++){ for(int j = 1; j <= 12; j++) if(cnt[i][j]) sum1 += 7; } for(int i = 1; i < m1; i++) if(cnt[y1][i]) sum1 += 7; if(cnt[y1][m1]){if(d1>7) sum1 += 7; else sum1 += d1;}//cout<<sum1<<endl; // t = (y2-2016)/400;sum2 += t*specialday;y2 = (y2-2016) % 400; for(int i = 0; i < y2; i++){ for(int j = 1; j <= 12; j++) if(cnt[i][j]) sum2 += 7; } for(int i = 1; i < m2; i++) if(cnt[y2][i]) sum2 += 7; if(cnt[y2][m2]){if(d2>7) sum2 += 7; else sum2 += d2;}//cout<<sum2<<endl; if(cnt[y1][m1]){ if(d1 > 7)cout<<sum2-sum1<<endl; else cout<<sum2-sum1+1<<endl; //1 2 3 4 5 6 7 } else cout<<sum2-sum1<<endl; } return 0;}
顺便贴上比赛时候的突发奇想查万年历,手动打表的,亏我想得出来,哈哈 ☺☺
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int cnt[10000][100];int main(){ memset(cnt, 0, sizeof cnt); cnt[0][2]=1; cnt[0][8]=1; cnt[1][5]=1; cnt[2][1]=1; cnt[2][10]=1; cnt[3][4]=1; cnt[3][7]=1; cnt[4][6]=1; cnt[5][2]=1; cnt[5][3]=1; cnt[5][11]=1; cnt[6][8]=1; cnt[7][5]=1; cnt[8][1]=1; cnt[8][4]=1; cnt[8][7]=1; cnt[9][9]=1; cnt[9][12]=1; cnt[10][10]=1; cnt[11][2]=1; cnt[11][3]=1; cnt[11][11]=1; cnt[12][5]=1; cnt[13][1]=1; cnt[13][10]=1; cnt[14][4]=1; cnt[14][7]=1; cnt[15][9]=1; cnt[15][12]=1; cnt[16][3]=1; cnt[16][11]=1; cnt[17][8]=1; cnt[18][5]=1; cnt[19][1]=1; cnt[19][10]=1; cnt[20][9]=1; cnt[20][12]=1; cnt[21][6]=1; cnt[22][2]=1; cnt[22][3]=1; cnt[22][11]=1; cnt[23][8]=1; cnt[24][10]=1; cnt[25][4]=1; cnt[25][7]=1; cnt[26][9]=1; cnt[26][12]=1; cnt[27][6]=1; //freopen("a.txt", "r", stdin); int T,y1,y2,m1,m2,d1,d2; long long sum1,sum2; scanf("%d", &T); while(T--){ sum1 = 0;sum2 = 0; scanf("%d%d%d%d%d%d", &y1, &m1, &d1, &y2, &m2, &d2); long long t = (y1-2016)/28;sum1 += t*48;y1 = (y1-2016) % 28; for(int i = 0; i < y1; i++){ for(int j = 1; j <= 12; j++) if(cnt[i][j]) sum1++; } for(int i = 1; i < m1; i++) if(cnt[y1][i]) sum1++; if(cnt[y1][m1]){if(d1>7) sum1 += 7; else sum1 += d1;}//cout<<sum1<<endl; // t = (y2-2016)/28;sum2 += t*48;y2 = (y2-2016) % 28; for(int i = 0; i < y2; i++){ for(int j = 1; j <= 12; j++) if(cnt[i][j]) sum2 += 7; } for(int i = 1; i < m2; i++) if(cnt[y2][i]) sum2 += 7; if(cnt[y2][m2]){if(d2>7) sum2 += 7; else sum2 += d2;}//cout<<sum2<<endl; cout<<sum2-sum1+1<<endl; } return 0;}
Thank you!
0 0
- UESTC 1299 Date 预处理、打表、找周期、前缀和
- UESTC 1269 ZhangYu Speech 预处理、前缀和
- UESTC 1256 昊昊喜欢运动 n^2的预处理 or 前缀和
- The 14th UESTC Programming Contest Final B - Banana Watch 预处理、前缀和
- FZU 2037Maximum Value Problem (打表预处理/找规律)
- ZOJ 3939The Lucky Week (打表预处理/找规律)
- 预处理之前缀和
- 2016 UESTC Training for Dynamic Programming C - 柱爷的下凡 预处理打表、背包问题
- UESTC 2016 Summer Training #4 Div.2 A - (。•_•。) 预处理打表
- hdu 5084 前缀和预处理
- UESTC 929 Post office【前缀和+贪心】
- HDU 4548 美素数 (素数打表+前缀和)
- HDU 2089 不要62 预处理+前缀和
- C. Star sky【前缀和预处理】
- HDU2089(打表预处理)
- CSUOJ 1299 - Number Transformation II 打表预处理水DP
- 打素数表找因子
- 4:前缀中的周期
- Shell脚本学习之sed详解
- [转] 汉语骂人最高境界!(爆笑)
- bzoj 1095
- Android 学习笔记(4)—— ToggleButton 、Switch
- Android 使用 Gradle 多渠道打包
- UESTC 1299 Date 预处理、打表、找周期、前缀和
- 记一个C++中的疑难杂症
- HDU 5631 Rikka with Graph(无向图去边搜索)
- 给easyui tree树加图标
- java中IO类的各种操作
- 腾讯2016软开实习生笔试题-编程1:蛇形矩阵
- 项目1-分数的雏形
- 基于JSP在线答题程序设计
- shiro整合redis做缓存