上海交大OJ 1008. 二哥買期貨
阿新 • • 發佈:2018-11-15
emmm....我的程式碼過不了OJ時間超時 只能得80分
-----------------------------------------------------------------------
Description
二哥想知道在一段時期內,一共有多少個交易日。期貨交易日的限定如下:
- 週六、週日不能交易
- 元旦期間(1月1日)不能交易
- 五一勞動節期間(5月1日至3日)不能交易
- 十一國慶節期間(10月1日至7日)不能交易
- 沒有在上述要求中提到的日期均可交易
Input Format
第一行有一個整數n,表示一共有n組資料。
每組資料都有一行,是兩個用空格分開的日期,分別為開始日期和結束日期。日期格式為YYYY-MM-DD(比如2010-11-11);資料保證開始日期不晚於結束日期。
對於所有資料:n≤365 n≤365
對於30%的資料:日期範圍從2010-11-23至2012-12-21
對於70%的資料:日期範圍從1900-01-01至9999-12-31
Output Format
輸出共n行,每行一個整數,對應於一組資料。
每組資料需要輸出在指定日期區間內,共有多少個交易日;區間的開始和結束日期也算在內(如果是交易日的話)。
Sample Input
4
2010-11-18 2010-11-20
2010-01-01 2010-01-01
2010-05-01 2010-05-03
2010-10-01 2010-10-07
Sample Output
2
0
0
0
用於計算是否為週末的方法基姆拉爾森 公式
//基姆拉爾森公式 //是週末返回 true 否返回false bool liuri(int y,int m,int d){ if(m == 1 || m == 2) //把一月和二月換算成上一年的十三月和是四月 { m += 12; y--; } int Week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; //0-6 代表著星期一到週日 if(Week == 5 || Week == 6) return true; //週末返回true 非週末返回false else return false; }
計算是否為閏年
//判斷是否閏年
//是 返回 1 否 返回 0
int judge(int Y){
//當Y是4的倍數且Y不是100的倍數 或者 Y是400的倍數
if((Y % 4 == 0 && Y % 100 != 0) || (Y % 400 == 0))
return 1;
else return 0;
}
總體程式碼
#include <cstdio>
using namespace std;
struct Node
{
int Year;
int Month;
int Day;
}e[365][2];
//judge[0] 非閏年
//judge[1] 閏年
int judgeY[2][13] = {
0,31,28,31,30,31,30,31,31,30,31,30,31,
0,31,29,31,30,31,30,31,31,30,31,30,31
};
//判斷是否閏年
//是 返回 1 否 返回 0
int judge(int Y){
//當Y是4的倍數且Y不是100的倍數 或者 Y是400的倍數
if((Y % 4 == 0 && Y % 100 != 0) || (Y % 400 == 0))
return 1;
else return 0;
}
//基姆拉爾森公式
//是週末返回 true 否返回false
bool liuri(int y,int m,int d){
if(m == 1 || m == 2) //把一月和二月換算成上一年的十三月和是四月
{
m += 12;
y--;
}
int Week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
//0-6 代表著星期一到週日
if(Week == 5 || Week == 6)
return true;
//週末返回true 非週末返回false
else return false;
}
//判斷是否放假 false - 不放 true - 放
bool fan(int y,int m,int d){
//返回p = true則是週末
bool p = liuri(y,m,d);
//滿足任意放假條件則返回true 否則返回 false
//週末 元旦 五一三天 國慶
if(p == true || (m == 1 && d == 1) || (m == 5 && d <= 3) || (m == 10 && d <= 7))
return true;
else return false;
}
//獲取請假時間
int getAnswer(int u){
//sum 記錄工作日天數
int sum = 0;
//jy 代表是否為閏年
int jy = judge(e[u][0].Year);
//迴圈累加
while (e[u][0].Year != e[u][1].Year || e[u][0].Month != e[u][1].Month || e[u][0].Day != e[u][1].Day) {
//當判斷返回這一天不是 節假日時sum++
if(fan(e[u][0].Year,e[u][0].Month,e[u][0].Day) == false)
sum++;
//天數+1
e[u][0].Day++;
//判斷是否應該進入下一個月
if(e[u][0].Day == judgeY[jy][e[u][0].Month] + 1){
//是 - month + 1
//day 重新回到1號
e[u][0].Month++;
e[u][0].Day = 1;
}
//判斷是否應該進入下一年
if(e[u][0].Month == 13){
//是 - year + 1
//month 重新回到一月
e[u][0].Year++;
e[u][0].Month = 1;
//重新判斷新的一年是否為閏年
jy = judge(e[u][0].Year);
}
}
//最後一天 判斷(防漏)
if(fan(e[u][0].Year,e[u][0].Month,e[u][0].Day) == false)
sum++;
return sum;
}
int main(int argc, char const *argv[]) {
//N行
int N;
scanf("%d",&N);
//輸入起始 終止年月日
for(int i = 0;i < N;i++){
for(int j = 0;j < 2;j++){
//getchar() 去除 ‘-’
scanf("%d",&e[i][j].Year);
getchar();
scanf("%d",&e[i][j].Month);
getchar();
scanf("%d",&e[i][j].Day);
}
}
//多組資料
for(int i = 0;i < N;i++){
printf("%d\n",getAnswer(i) );
}
return 0;
}