日曆問題詳解 程式設計練習題(100)

2021-08-29 00:17:55 字數 2761 閱讀 9389

目錄

題目:分析:

c++ stl**:

總結:日曆問題

問題描述

在我們先在使用的日曆中,閏年被定義為能被4整除的年份,但是能被100整除而不能被400整除的年是例外,他們不是閏年。例如:1700,1800,1900和2023年不是閏年,而1600,2000和2400是閏年。給定從公元2023年1月1日開始逝去的天數,你的任務是給出這一天是哪年哪月哪日星期幾

輸入資料

輸入包含若干行,每行包含乙個正整數,表示從2023年1月1日開始逝去的天數。輸入最後最後一行是-1,不必處理。可以假設結果的年份不會超過9999. 

輸出要求

對每個測試樣例,輸出一行,該行包含對應的日期和星期幾。合適為「yyyy-mm-dd dayofweek」。其中「dayofweek」必須是下面中的乙個:「monday」,「tuesday」,「wednesday」,「thursday,「friday」,「saturday」,「sunday」。

輸入樣例

1730

1740

1750

1751

-1輸出樣例

2004-09-26 sunday

2004-10-06 wednesday

2004-10-16 saturday

2004-10-16 sunday

首先這道題看著很複雜,因為涉及閏年和平年天數不一樣,閏年366天,2月為29天;平年365天,2月為28天。而且每月的天數也不相同,1、3、5、7、8、10、12月為31天,4、6、9、11月為30天,沒有太大的規律可循,所以不能用 逝去的天數  取餘一年的天數 。只有星期是每星期都是7天,所以可以用  逝去的天數  取餘  7來判斷星期幾。

首先我們可能想到最蠢的辦法一天一天判斷,每到7天星期歸0,每到月末月數+1,每到12月年數+1,月數歸1.但這個辦法太蠢,如果2023年的話估計得算到死。

所以我們可能會想到先判斷是哪一年,再判斷是哪一月,再計算出是哪一天,最後計算是星期幾。在年和月判斷的時候最開始我們可能是想到用if()else語句,先判斷剩餘天數是否大於當前年所有天數(閏年366天,平年365天),然後再判斷如果是閏年則減去366天,如果是平年則減去365天。最後剩餘天數是不夠一年所含天數的,所以年份算出來了。同樣可以迴圈判斷求出所在月份。最後天數+1就可以了。

那麼問題來了,我們怎麼判斷年份是閏年還是平年,怎麼判斷月份的天數,我們可能想到用if()else語句來判斷,那麼我們每次都要判斷一下,如果我們事先將一年中每月所含天數用乙個陣列存起來的話是不是更方便判斷,同樣,我們是不是也可以用陣列將星期幾也存進去。所以我們選擇陣列儲存年份所含天數,月份所含天數,星期幾字串。

最後,上面我們是一年一年判斷,然後減去年份天數(366/365),那我們在判斷一年是閏年後,我們是不是可以肯定接下來的3年都是平年,如果剩餘天數夠的話我們是不是就可以直接減去3*365天。然後再判斷是否是閏年。這樣執行時間又能變為原來1/4。

注意:天數最後要+1;要用取餘(%)判斷是否是閏年;輸出格式要控制好,日期格式是2000-09-01,如過剩餘天數是個位數,則要在前邊加上0,具體做法可以參照下面**,c++控制資料按照指定位數輸出,主要用到c++兩個輸出控制,setw(位數),和setfill(指定字元)。需要加上頭#include 。

cout << setw(2) << setfill('0') <#include #include using namespace std;

int main()

,

};//monthofy[0]表示平年每月天數,monthofy[1]表示閏年每月天數

char weeks[7][12] = ;/*星期字串,2023年1月1號是週六,所以從週六開始*/

int year = 2000;/*當前年份*/

int yd[2] = ;/*yd[1]表示潤年,yd[0]表示平年*/

int month = 0;/*月份*/

int day = 0;/*儲存逝去的天數*/

int week = 0;/*標識星期幾*/

int temp;/*暫存中間變數*/

int yt = 0; /*標識平年還是潤年*/

while(1)/*從輸入流讀入逝去的天數*/

elapseday.push_back(temp);/*將temp插入到elapseday末尾*/

}vector::iterator i = elapseday.begin();/*迭代器遍歷vector*/

for( ;i != elapseday.end(); i++)/*迴圈輸出每個逝去的天數對應的日期*/

for(month = 1; day >= monthofy[yt][month]; month++)/*month對應月份,判斷當前剩餘天數是否大於本月所含天數,小於的話就退出for迴圈*/

cout << year << '-' ;

cout << setw(2) << setfill('0') 《在答題的過程中要仔細閱讀題目,首先分析可以使用什麼資料結構來存題目中出現的資料,然後再分析此種資料結構是否可行,不行的話換個資料結構。就這樣what(用什麼資料結構),why(為什麼用這種資料結構,有什麼好處)不斷重複優化。這些在寫公司面試題或者要求時間空間效率的時候是比較好的方法。在做ccf-csp考試前兩題的時候估計幾乎不怎麼用,只要把題做出來,能得滿分就行,對於**風格,時間空間效率只要滿足條件就行,要求不太苛刻。

題目中充分利用了陣列,不少題目都可以很巧妙的應用陣列,比如ccf-csp2013-12-1這道題,詳見稍後再寫。

程式設計練習題

程式student create student studs,int n student 是乙個結構型別,包含姓名 成績和指標域。studs 陣列中儲存了n個 student 記錄。create 函式的功能是編寫根據 studs 陣列建立乙個鍊錶,鍊錶中結點按成績降序排列,函式返回煉表頭指標。inc...

數碼管程式設計題 程式設計練習題(100)

目錄 問題 分析 c 總結 7.問題描述 液晶數碼管用七筆阿拉數字表示的十個數字,把橫和豎的一 個短劃都稱為一筆,即 有 筆,有 筆等。對於十個數字一種排列,要做到兩相鄰數字都可以由另乙個數字加上幾筆或減去幾筆組成,但不能又加又減。比如 是允許的,不允許。任意輸入一組數,判斷是否符合上述規則,注意,...

數碼管程式設計題 程式設計練習題(100)

目錄 問題 分析 c 總結 7.問題描述 液晶數碼管用七筆阿拉數字表示的十個數字,把橫和豎的一 個短劃都稱為一筆,即 有 筆,有 筆等。對於十個數字一種排列,要做到兩相鄰數字都可以由另乙個數字加上幾筆或減去幾筆組成,但不能又加又減。比如 是允許的,不允許。任意輸入一組數,判斷是否符合上述規則,注意,...