算法與程序?qū)嵺`習(xí)題解答4(日期時(shí)間)_第1頁(yè)
算法與程序?qū)嵺`習(xí)題解答4(日期時(shí)間)_第2頁(yè)
算法與程序?qū)嵺`習(xí)題解答4(日期時(shí)間)_第3頁(yè)
算法與程序?qū)嵺`習(xí)題解答4(日期時(shí)間)_第4頁(yè)
算法與程序?qū)嵺`習(xí)題解答4(日期時(shí)間)_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

目錄CS41:判斷閏年1CS42:細(xì)菌繁殖3CS43:日歷問(wèn)題5CS44:瑪雅歷7CS45:時(shí)區(qū)間時(shí)間的轉(zhuǎn)換9CS46:不吉利的日期14CS47:特殊日歷計(jì)算15《算法與程序?qū)嵺`》習(xí)題解答4——日期和時(shí)間處理在很多具體的程序設(shè)計(jì)中,經(jīng)常會(huì)遇到與日期和時(shí)間處理相關(guān)的問(wèn)題。首先我們來(lái)了解一下日期和時(shí)間格式。世界各地有多種格式來(lái)表示日期和時(shí)間。對(duì)于日期的常用格式,在中國(guó)常采用格式的是“年年年年/月月/日日”或?qū)憺橛⒄Z(yǔ)縮略表示的”yyyy/mm/dd”,而北美所用的日期格式則為“月月/日日/年年年年”或”mm/dd/yyyy”,如將“2009/11/07”改成這種格式,對(duì)應(yīng)的則是”11/07/2009”。對(duì)于時(shí)間的格式,則常有12小時(shí)制和24小時(shí)制的表示方法,24小時(shí)制用0-24來(lái)表示一天中的24小時(shí),而12小時(shí)制只采用1-12表示小時(shí),再加上am/pm來(lái)表示上午或下午,比如”17:30:00”是采用24小時(shí)制來(lái)表示時(shí)間,而對(duì)應(yīng)的12小時(shí)制的表示方法是”05:30:00pm”基本思想:這類問(wèn)題一般會(huì)涉及到不同日歷表示法之間的相互轉(zhuǎn)換。解決此類問(wèn)題的基本思想是找到一種公共的基準(zhǔn),并通過(guò)基準(zhǔn)進(jìn)行不同日歷之間的轉(zhuǎn)換。日期和時(shí)間處理問(wèn)題一般不涉及很難的算法,但有時(shí)會(huì)有一些特殊情況需要處理,如果考慮不到就會(huì)出錯(cuò)。因此需要一些耐心處理細(xì)節(jié)問(wèn)題,可以比較好地訓(xùn)練編程的嚴(yán)謹(jǐn)性。下面通過(guò)一些具體的實(shí)例說(shuō)明日期和時(shí)間處理上的常見問(wèn)題及其解答。對(duì)于每一道例題,我們將給出問(wèn)題描述、輸入輸出要求、輸入輸出樣例、解題思路、參考程序和實(shí)現(xiàn)中常見的問(wèn)題。CS41:判斷閏年(來(lái)源:2733)問(wèn)題描述:判斷某年是否是閏年。公歷紀(jì)年法中,能被4整除的大多是閏年,但能被100整除而不能被400整除的年份不是閏年,如1900年是平年,2000年是閏年。輸入:輸入數(shù)據(jù)一行,僅含一個(gè)整數(shù)a(0<a<3000)。輸出:輸出要求一行,如果公元a年是閏年輸出Y,否則輸出N。輸入樣例:2006輸出樣例:N解題思路:這個(gè)題目主要考察閏年的定義,使用基本的邏輯判斷語(yǔ)句就可以了??紤]到輸入的范圍在0到3000之間,所以判斷閏年時(shí)不必考慮能被3200整除的年份不是閏年的判定條件。程序應(yīng)該包括三個(gè)基本的步驟:正確讀入要判定的年份a;判定a是否為閏年;給出正確的輸出。閏年的判定方法判定公歷閏年遵循的一般規(guī)律為:四年一閏,百年不閏,四百年再閏.公歷閏年的精確計(jì)算方法?(按一回歸年365天5小時(shí)48分45.5秒)①、普通年能被4整除且不能被100整除的為閏年。(如2004年就是閏年,1901年不是閏年)②、世紀(jì)年能被400整除的是閏年。(如2000年是閏年,1900年不是閏年)③、對(duì)于數(shù)值很大的年份,這年如果能整除3200,并且能整除172800則是閏年。如172800年是閏年,86400年不是閏年(因?yàn)殡m然能整除3200,但不能整除172800)(此按一回歸年365天5h48'45.5''計(jì)算)。此外,如依照現(xiàn)有太陽(yáng)年的長(zhǎng)度與上述閏年規(guī)則,每8000年又約差一日,因此約翰·赫歇爾提議每逢4000的倍數(shù)不閏,如西元4000年。但距此一年份來(lái)臨尚有約二千年之遙,因此還未曾真正納入規(guī)則或?qū)嵤┻^(guò)。又由于地球公轉(zhuǎn)速率的不穩(wěn)定與眾多影響因素,屆時(shí)是否需要納入此規(guī)則仍有疑問(wèn)。原因:若一年按365天5h48'46''(此時(shí)86400年也是閏年)計(jì)算,一年日數(shù)必須是整數(shù),不便將零時(shí)數(shù)計(jì)入,所以取365天為一年,則余5時(shí)48分46秒,積至4年約滿一日,所以4年一“閏日”,謂之“閏年”,無(wú)“閏日”之年為平年,即平年365天,閏年366天。但到4年之時(shí),僅有23時(shí)15分4秒閏一日,欠缺44分56秒;積至100年(25閏)時(shí)就欠缺18時(shí)43分20秒,約合3/4日,所以滿100年不閏;此時(shí)又余5時(shí)16分40秒,積至400年余21時(shí)6分40秒又閏;又欠缺2時(shí)53分20秒,積至3200年計(jì)欠缺23時(shí)6分40秒,所以滿3200年不閏;此時(shí)又余53分20秒,積至86400年剛好24時(shí)又一閏,這是不余不欠,需重計(jì)算,所以按陽(yáng)歷計(jì)算就有上面的閏年規(guī)則。按一回歸年365天5h48'45.5''計(jì)算:3200年多出16000小時(shí)153600分145600秒=18600小時(shí)26分40秒,共32*24+8=136個(gè)閏年=776*24=18624小時(shí)>18600小時(shí),所以只能算到775個(gè)閏年,3200不是閏年,于是775*24=18600,多出了26分40秒怎么辦需要多少個(gè)周期彌補(bǔ)?答案是54個(gè)周期,為172800年,因?yàn)?72800/3200=54個(gè)周期54*26分40秒=1404分2160秒=24小時(shí)。公元前閏年規(guī)則1,非整百年:年數(shù)除以4余數(shù)為1是閏年,即公元前1、5、9……年;2,整百年:年數(shù)除以400余數(shù)為1是閏年,年數(shù)除以3200余數(shù)為1,不是閏年,年數(shù)除以172800余1又為閏年,即公元前401、801……年。其中,判斷輸入年份是否為閏年根據(jù)個(gè)人的思考習(xí)慣可以有不同的判定順序。參考解法一:分段排除:如果a%4!=0,則a不是閏年;否則如果a%100==0&&a%400!=0,則a不是閏年;否則a是閏年。參考解法二:列出所有閏年的可能條件,滿足條件則為閏年,否則判為非閏年:如果(a%400==0||(a%4==0&&a%100!=0)),則a是閏年;否則a不是閏年。參考程序1:#include<stdio.h>intmain(){ inta; scanf("%d",&a); if(a%4!=0) printf("N\n"); elseif(a%100==0&&a%400!=0) printf("N\n"); else printf("Y\n"); return0;}參考程序2:#include<stdio.h>intmain(){ inta; scanf("%d",&a); if((a%4==0&&a%100!=0)||a%400==0) printf("Y\n"); else printf("N\n"); return0;}CS42:細(xì)菌繁殖(來(lái)源:2712)問(wèn)題描述:一種細(xì)菌的繁殖速度是每天成倍增長(zhǎng)。例如:第一天有10個(gè),第二天就變成20個(gè),第三天變成40個(gè),第四天變成80個(gè),……。現(xiàn)在給出第一天的日期和細(xì)菌數(shù)目,要你寫程序求出到某一天的時(shí)候,細(xì)菌的數(shù)目。輸入:第一行有一個(gè)整數(shù)n,表示測(cè)試數(shù)據(jù)的數(shù)目。其后n行每行有5個(gè)整數(shù),整數(shù)之間用一個(gè)空格隔開。第一個(gè)數(shù)表示第一天的月份,第二個(gè)數(shù)表示第一天的日期,第三個(gè)數(shù)表示第一天細(xì)菌的數(shù)目,第四個(gè)數(shù)表示要求的那一天的月份,第五個(gè)數(shù)表示要求的那一天的日期。已知第一天和要求的一天在同一年并且該年不是閏年,要求的一天一定在第一天之后。數(shù)據(jù)保證要求的一天的細(xì)菌數(shù)目在整數(shù)范圍內(nèi)。輸出:對(duì)于每一組測(cè)試數(shù)據(jù),輸出一行,該行包含一個(gè)整數(shù),為要求的一天的細(xì)菌數(shù)。輸入樣例:2111122281032輸出樣例:240解題思路:這題實(shí)際上是求給定的兩天之間間隔的天數(shù)n,第一天的細(xì)菌數(shù)乘以2的n次方就是題目的答案。每個(gè)月的天數(shù)因?yàn)椴缓芤?guī)則,如果在程序中用規(guī)則描述會(huì)比較麻煩,所以可以使用一個(gè)數(shù)組將每個(gè)月的天數(shù)存起來(lái)。整個(gè)計(jì)算過(guò)程可以描述如下:讀入測(cè)試樣例數(shù)n;做n次:1.讀入兩個(gè)日期及第一天的細(xì)菌數(shù); 2.將兩個(gè)日期轉(zhuǎn)換為當(dāng)年的第幾天; 3.得到兩個(gè)天數(shù)的差,即它們中間間隔的天數(shù)m; 4.用第一天的細(xì)菌數(shù)乘以2的m次方等到x; 5.輸出x;思考題:如果要求的最終細(xì)菌數(shù)目可能超過(guò)整數(shù)所能表示的范圍,此題該如何解決?參考程序1:#include<stdio.h>intmain(){ intdays[12]={31,28,31,30,31,30,31,31,30,31,30,31}; intn; inti,j; scanf("%d",&n); for(i=0;i<n;i++) { intmonth_1,day_1,month_2,day_2,num; scanf("%d%d%d%d%d",&month_1,&day_1,&num,&month_2,&day_2); intsum=0; for(j=month_1;j<month_2;j++) sum+=days[j-1]; sum-=day_1; sum+=day_2; longnNum=num; for(j=0;j<sum;j++) nNum*=2; printf("%ld\n",nNum); } return0;}參考程序2:#include<stdio.h>intdays[]={0,31,28,31,30,31,30,31,31,30,31,30,31};intmain(){ intn; inti; intmon1,date1,mon2,date2,num1; scanf("%d",&n); while(n--) { scanf("%d%d%d%d%d",&mon1,&date1,&num1,&mon2,&date2); intsum=date2-date1; for(i=mon1;i<mon2;i++) sum+=days[i]; longnum=num1; for(i=0;i<sum;i++) num*=2; printf("%ld\n",num); } return0;}CS43:日歷問(wèn)題(來(lái)源:2964)問(wèn)題描述:在我們現(xiàn)在使用的日歷中,閏年被定義為能被4整除的年份,但是能被100整除而不能被400整除的年是例外,它們不是閏年。例如:1700,1800,1900和2100不是閏年,而1600,2000和2400是閏年。給定從公元2000年1月1日開始逝去的天數(shù),你的任務(wù)是給出這一天是哪年哪月哪日星期幾。輸入:輸入包含若干行,每行包含一個(gè)正整數(shù),表示從2000年1月1日輸出:對(duì)每個(gè)測(cè)試樣例,輸出一行,該行包含對(duì)應(yīng)的日期和星期幾。格式為“YYYY-MM-DDDayOfWeek”,其中“DayOfWeek”必須是下面中的一個(gè):“Sunday”,“Monday”,“Tuesday”,“Wednesday”,“Thursday”,“Friday”and“Saturday”。樣例輸入:1730174017501751-1樣例輸出:2004-09-26Sunday2004-10-06Wednesday2004-10-16Saturday2004-10-17Sunday解題思路:這道題目使用的背景知識(shí)是閏年的定義和公歷日歷中一年12個(gè)月中每個(gè)月的日期數(shù)。根據(jù)題目要求,所有涉及的數(shù)值都是用整數(shù)可以表示的。這個(gè)問(wèn)題可以分解成兩個(gè)彼此獨(dú)立的問(wèn)題:一個(gè)是要求的那天是星期幾,另一是要求的那天是哪年哪月那天。第一個(gè)問(wèn)題比較簡(jiǎn)單,知道2000年1月1日是星期幾后,只要用給定的日期對(duì)7取模,就可以知道要求的一天是星期幾。第二個(gè)問(wèn)題相對(duì)麻煩一些。我們用year,month,date分別表示要求的日期的年、月、日。當(dāng)輸入一個(gè)整數(shù)n時(shí),如果n大于等于一年的天數(shù),就用n減去一年的天數(shù),直到n比一年的天數(shù)少(這時(shí)假設(shè)剩下天數(shù)為m),一共減去多少年year就等于多少;如果m大于等于一個(gè)月的天數(shù),就用m減去一個(gè)月的天數(shù),直到m比一個(gè)月的天數(shù)少(這時(shí)假設(shè)剩下的天數(shù)為k),一共減去多少個(gè)月month參考程序:#include<stdio.h>inttype(int);//函數(shù)聲明charweek[7][10]={"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};intyear[2]={365,366};//非閏年的天數(shù)、閏年的天數(shù)intmonth[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};intmain(){ intdays,dayofweek;//days表示輸入的天數(shù),dayofweek表示星期幾 inti=0,j=0; //freopen("in.txt","r",stdin); while(scanf("%d",&days)&&days!=-1) { dayofweek=days%7; for(i=2000;days>=year[type(i)];i++) days-=year[type(i)]; for(j=0;days>=month[type(i)][j];j++) days-=month[type(i)][j]; printf("%d-%02d-%02d%s\n",i,j+1,days+1,week[dayofweek]); } return0;}inttype(intm)//判斷第m年是否為閏年,是則返回1,否則返回0{ if(m%4!=0||(m%100==0&&m%400!=0))return0; else return1;}注意事項(xiàng):?jiǎn)栴}一:邏輯過(guò)于復(fù)雜,導(dǎo)致程序出錯(cuò)。問(wèn)題二:沒(méi)有將判斷閏年的代碼抽象成函數(shù),使得主程序代碼不夠清晰。問(wèn)題三:多數(shù)出錯(cuò)的地方在于算出從2000年到當(dāng)前年經(jīng)歷了多少個(gè)閏年。很多同學(xué)都錯(cuò)在多算一個(gè)或者少算一個(gè)。另外計(jì)算閏年不能用循環(huán),否則會(huì)超時(shí)。CS44:瑪雅歷(來(lái)源:2965)問(wèn)題描述:上周末,M.A.教授對(duì)古老的瑪雅有了一個(gè)重大發(fā)現(xiàn)。從一個(gè)古老的節(jié)繩(瑪雅人用于記事的工具)中,教授發(fā)現(xiàn)瑪雅人使用了一個(gè)一年有365天的叫做Haab的日歷。這個(gè)Haab日歷擁有19個(gè)月,在開始的18個(gè)月,一個(gè)月有20天,月份的名字分別是pop,no,zip,zotz,tzec,xul,yoxkin,mol,chen,yax,zac,ceh,mac,kankin,muan,pax,koyab,cumhu。這些月份中的日期用0到19表示。Haab歷的最后一個(gè)月叫做uayet,它只有5天,用0到4表示?,斞湃苏J(rèn)為這個(gè)日期最少的月份是不吉利的,在這個(gè)月法庭不開庭,人們不從事交易,甚至沒(méi)有人打掃屋中的走廊。因?yàn)樽诮痰脑颍斞湃诉€使用了另一個(gè)日歷,在這個(gè)日歷中年被稱為Tzolkin(holly年),一年被分成13個(gè)不同的時(shí)期,每個(gè)時(shí)期有20天,每一天用一個(gè)數(shù)字和一個(gè)單詞相組合的形式來(lái)表示。使用的數(shù)字是1~13,使用的單詞共有20個(gè),它們分別是:imix,ik,akbal,kan,chicchan,cimi,manik,lamat,muluk,ok,chuen,eb,ben,ix,mem,cib,caban,eznab,canac,ahau。注意:一年中的每一天都有著明確的描述,比如,在一年的開始,日期如下描述:1imix,2ik,3akbal,4kan,5chicchan,6cimi,7manik,8lamat,9muluk,10ok,11chuen,12eb,13ben,1ix,2mem,3cib,4caban,5eznab,6canac,7ahau,,8imix,9ik,10akbal,...。也就是說(shuō)數(shù)字和單詞各自獨(dú)立循環(huán)使用。Haab歷和Tzolkin歷中的年都用數(shù)字0,1,…表示,數(shù)字0表示世界的開始。所以第一天被表示成:Haab:0.pop0Tzolkin:1imix0請(qǐng)幫助M.A.教授寫一個(gè)程序可以把Haab歷轉(zhuǎn)化成Tzolkin歷。輸入:Haab歷中的數(shù)據(jù)由如下的方式表示:日期.月份年數(shù)第一行表示要轉(zhuǎn)化的Haab歷的數(shù)據(jù)量。下面的每一行表示一個(gè)日期,年數(shù)小于5000。輸出:Tzolkin歷中的數(shù)據(jù)由如下的方式表示:天數(shù)字天名稱年數(shù)第一行表示需要轉(zhuǎn)化的Haab歷的數(shù)據(jù)量。下面的每一行表示一個(gè)日期。樣例輸入:310.zac00.pop010.zac1995樣例輸出:33chuen01imix09cimi2801解題思路:這道題問(wèn)的是如何將Haab歷的日期轉(zhuǎn)換為Tzolkin歷的日期。首先我們要搞清楚這兩種日歷記述日期的規(guī)則。Haab歷每年365天,分成19個(gè)月,前18個(gè)月每月20天,第19個(gè)月有5天,19個(gè)月的名字分別用不同的字符串表示。每個(gè)月的日期是從0開始順序記錄的。若要計(jì)算出某個(gè)月的某一天是當(dāng)年的第幾天,可以將相應(yīng)的月份用0~18表示,然后通過(guò)公式:月份*20+日期+1來(lái)計(jì)算。Tzolkin歷一年有260天,每個(gè)日期由數(shù)字部分和字符串部分組合而成。日期部分從1~13循環(huán)使用,字符串部分由20個(gè)不同的字符串循環(huán)取出使用??梢钥闯?,Tzolkin歷中的日期的兩個(gè)組成部分是彼此獨(dú)立的,對(duì)于一年中的某一天,可以分別求出其數(shù)字部分和字符串部分,然后將其簡(jiǎn)單組合起來(lái)。這里正好260是13和20的最小公倍數(shù),所以一年中沒(méi)有兩天是一樣的,并且數(shù)字和字符串的所有組合都被用來(lái)表示一年的某一天了。接下來(lái)我們可以分析一下題目的具體解法??偟乃悸肥鞘紫扔?jì)算出給出的Haab歷表示的日期是世界開始后的第幾天(假設(shè)是k),然后用k除以260得到Tzolkin歷的年份,再用k對(duì)260取模得到m,用m分別對(duì)13和20取模得到d和s,d和Tzolkin歷中第s個(gè)字符串的組合就是要求的日期。這里需要注意的是如果我們把世界的第1天用0表示,第260天用259表示,則正好用這個(gè)數(shù)字除以260得到Tzolkin歷的年份,m對(duì)13取模后得到0到12的值,這個(gè)值要加1才能用于表示Tzolkin歷的日期,同時(shí)m對(duì)20取模后得到0~19的數(shù)值,分別表示取20個(gè)字符串中的一個(gè)。如果我們用字符串?dāng)?shù)組來(lái)存儲(chǔ)這20個(gè)字符串,則0~19的取值正好對(duì)應(yīng)需要的字符串的數(shù)組下標(biāo)。參考程序:#include<stdio.h>#include<string.h>constintNAMELEN=10;charmonth1[19][NAMELEN]={ "pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen","yax","zac", "ceh","mac","kankin","muan","pax","koyab","cumhu","uayet"};charmonth2[20][NAMELEN]={ "imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk", "ok","chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"};intmain(){ intnCase,i,m; //freopen("in.txt","r",stdin); scanf("%d",&nCase); printf("%d\n",nCase); for(i=0;i<nCase;i++) { intday,year,dates; charmonth[NAMELEN]; scanf("%d.%s%d",&day,month,&year);//讀出Haab歷的年月日 for(m=0;m<19;m++) if(!strcmp(month1[m],month))break;//找到月份對(duì)應(yīng)的數(shù)字 dates=year*365+m*20+day;//計(jì)算距離世界開始的天數(shù),從0卡是 printf("%d%s%d\n",1+dates%13,month2[dates%20],dates/260); } return0;}注意事項(xiàng):?jiǎn)栴}一:一個(gè)非常不起眼,但卻不容易查出來(lái)的問(wèn)題是,有人在建立月份名稱數(shù)組時(shí),將個(gè)別月份的名字敲錯(cuò)了一兩個(gè)字母,導(dǎo)致程序運(yùn)行出錯(cuò)。問(wèn)題二:有些人在計(jì)算Tzolkin歷時(shí),把程序中的1+dates%13寫成(dates+1)%13,導(dǎo)致本應(yīng)該從1~13的數(shù)變成0~12的數(shù)。CS45:時(shí)區(qū)間時(shí)間的轉(zhuǎn)換(來(lái)源:2966)問(wèn)題描述:直到19世紀(jì),時(shí)間校準(zhǔn)是一個(gè)純粹的地方現(xiàn)象。每一個(gè)村莊當(dāng)太陽(yáng)升到最高點(diǎn)的時(shí)候把他們的時(shí)鐘調(diào)到中午12點(diǎn)。一個(gè)鐘表制造商人家或者村里主表的時(shí)間被認(rèn)為是官方時(shí)間,市民們把自家的鐘表和這個(gè)時(shí)間對(duì)齊。每周一些熱心的市民會(huì)帶著時(shí)間標(biāo)準(zhǔn)的表,游走大街小巷為其他市民對(duì)表。在城市之間旅游的話,在到達(dá)新地方的時(shí)候需要把懷表校準(zhǔn)。但是,當(dāng)鐵路投入使用之后,越來(lái)越多的人頻繁地長(zhǎng)距離地往來(lái),時(shí)間變得越來(lái)越重要。在鐵路的早期,時(shí)刻表非常讓人迷惑,每一個(gè)所謂的??繒r(shí)間都是基于??康攸c(diǎn)的當(dāng)?shù)貢r(shí)間。時(shí)間的標(biāo)準(zhǔn)化對(duì)于鐵路的高效運(yùn)營(yíng)變得非常重要。在1878年,加拿大人SirSanfordFleming提議使用一個(gè)全球的時(shí)區(qū)(這個(gè)建議被采納,并衍生了今天我們所使用的全球時(shí)區(qū)的概念),他建議把世界分成24個(gè)時(shí)區(qū),每一個(gè)跨越15度經(jīng)線(因?yàn)榈厍虻慕?jīng)度360度,劃分成24塊后,一塊為15度)。SirSanfordFleming的方法解決了一個(gè)全球性的時(shí)間混亂的問(wèn)題。美國(guó)鐵路公司于1883年11月18日使用了Fleming提議的時(shí)間方式。1884年一個(gè)國(guó)際子午線會(huì)議在華盛頓召開,他的目的是選擇一個(gè)合適的本初子午線。大會(huì)最終選定了格林威治為標(biāo)準(zhǔn)的0度。盡管時(shí)區(qū)被確定了下來(lái),但是各個(gè)國(guó)家并沒(méi)有立刻更改他們的時(shí)間規(guī)范,在美國(guó),盡管到1895年已經(jīng)有很多州開始使用標(biāo)準(zhǔn)時(shí)區(qū)時(shí)間,國(guó)會(huì)直到1918年才強(qiáng)制使用會(huì)議制定的時(shí)間規(guī)范。今天各個(gè)國(guó)家使用的是一個(gè)Fleming時(shí)區(qū)規(guī)范的一個(gè)變種,中國(guó)一共跨越了5個(gè)時(shí)區(qū),但是使用了一個(gè)統(tǒng)一的時(shí)間規(guī)范,比CoordinatedUniversalTime(UTC,格林威制時(shí)間)早8個(gè)小時(shí)。俄羅斯也擁護(hù)這個(gè)時(shí)區(qū)規(guī)范,盡管整個(gè)國(guó)家使用的時(shí)間和標(biāo)準(zhǔn)時(shí)區(qū)提前了1個(gè)小時(shí)。澳大利亞使用3個(gè)時(shí)區(qū),其中主時(shí)區(qū)提前于他按Fleming規(guī)范的時(shí)區(qū)半小時(shí)。很多中東國(guó)家也使用了半時(shí)時(shí)區(qū)(即不是按照Fleming的24個(gè)整數(shù)時(shí)區(qū))。因?yàn)闀r(shí)區(qū)是對(duì)經(jīng)度進(jìn)行劃分,在南極或者北極工作的科學(xué)家直接使用了UTC時(shí)間,否則南極大陸將被分解成24個(gè)時(shí)區(qū)。時(shí)區(qū)的轉(zhuǎn)化表如下:UTC(CoordinatedUniversalTime)GMT(GreenwichMeanTime),定義為UTC小時(shí)BST(BritishSummerTime),定義為UTC+1小時(shí)IST(IrishSummerTime),定義為UTC+1小時(shí)WET(WesternEuropeTime),定義為UTC小時(shí)WEST(WesternEuropeSummerTime),定義為UTC+1小時(shí)CET(CentralEuropeTime),定義為UTC+1小時(shí)CEST(CentralEuropeSummerTime),定義為UTC+2小時(shí)EET(EasternEuropeTime),定義為UTC+2小時(shí)EEST(EasternEuropeSummerTime),定義為UTC+3小時(shí)MSK(MoscowTime),定義為UTC+3小時(shí)MSD(MoscowSummerTime),定義為UTC+4小時(shí)AST(AtlanticStandardTime),定義為UTC-4小時(shí)ADT(AtlanticDaylightTime),定義為UTC-3小時(shí)NST(NewfoundlandStandardTime),定義為UTC-3.5小時(shí)NDT(NewfoundlandDaylightTime),定義為UTC-2.5小時(shí)EST(EasternStandardTime),定義為UTC-5小時(shí)EDT(EasternDaylightSavingTime),定義為UTC-4小時(shí)CST(CentralStandardTime),定義為UTC-6小時(shí)CDT(CentralDaylightSavingTime),定義為UTC-5小時(shí)MST(MountainStandardTime),定義為UTC-7小時(shí)MDT(MountainDaylightSavingTime),定義為UTC-6小時(shí)PST(PacificStandardTime),定義為UTC-8小時(shí)PDT(PacificDaylightSavingTime),定義為UTC-7小時(shí)HST(HawaiianStandardTime),定義為UTC-10小時(shí)AKST(AlaskaStandardTime),定義為UTC-9小時(shí)AKDT(AlaskaStandardDaylightSavingTime),定義為UTC-8小時(shí)AEST(AustralianEasternStandardTime),定義為UTC+10小時(shí)AEDT(AustralianEasternDaylightTime),定義為UTC+11小時(shí)ACST(AustralianCentralStandardTime),定義為UTC+9.5小時(shí)ACDT(AustralianCentralDaylightTime),定義為UTC+10.5小時(shí)AWST(AustralianWesternStandardTime),定義為UTC+8小時(shí)下面給出了一些時(shí)間,請(qǐng)?jiān)诓煌瑫r(shí)區(qū)之間進(jìn)行轉(zhuǎn)化。輸入:輸入的第一行包含了一個(gè)整數(shù)N,表示有N組測(cè)試數(shù)據(jù)。接下來(lái)N行,每一行包括一個(gè)時(shí)間和兩個(gè)時(shí)區(qū)的縮寫,它們之間用空格隔開。時(shí)間由標(biāo)準(zhǔn)的a.m./p.m給出。midnight表示晚上12點(diǎn)(12:00a.m.),noon表示中午12點(diǎn)(12:00p.m.)。輸出:假設(shè)輸入行給出的時(shí)間是在第一個(gè)時(shí)區(qū)中的標(biāo)準(zhǔn)時(shí)間,要求輸出這個(gè)時(shí)間在第二個(gè)時(shí)區(qū)中的標(biāo)準(zhǔn)時(shí)間。樣例輸入:4noonHSTCEST11:29a.m.ESTGMT6:01p.m.CSTUTC12:40p.m.ADTMSK樣例輸出:midnight4:29p.m.12:01a.m.6:40p.m.解題思路:這個(gè)題目要求在兩個(gè)時(shí)區(qū)之間進(jìn)行時(shí)間的轉(zhuǎn)換。我們根據(jù)每個(gè)時(shí)區(qū)與格林威治時(shí)間的轉(zhuǎn)換公式可以推算出兩個(gè)時(shí)區(qū)之間的差別。問(wèn)題的解決方法不難想到,只是日期處理類問(wèn)題具有共同的特點(diǎn)就是輸入輸出比較麻煩,有一些需要特殊處理的情況,例如轉(zhuǎn)換后多出一天或少了一天的情況需要處理。具體到這個(gè)題目來(lái)說(shuō):輸入時(shí),除了一般的時(shí)間表示法:時(shí):分a.m/p.m.之外,要特殊處理noon和midnight;在直接通過(guò)格林威治時(shí)間進(jìn)行轉(zhuǎn)換后,要判斷是否超過(guò)一天或減少了一天的情況;在輸出時(shí)間時(shí),要對(duì)noon和midnight進(jìn)行特殊處理。解決這個(gè)問(wèn)題時(shí),關(guān)鍵的是確定兩個(gè)時(shí)區(qū)之間的時(shí)差。因?yàn)闀r(shí)區(qū)是用字符串形式給出的,所以要先將時(shí)區(qū)對(duì)應(yīng)到該時(shí)區(qū)與格林威治時(shí)間的時(shí)差上。有了每個(gè)時(shí)區(qū)與格林威治時(shí)間的時(shí)差,就可以計(jì)算任意兩個(gè)時(shí)區(qū)之間的時(shí)差。參考程序:#include<stdio.h>#include<string.h>intdifference(char*zone1,char*zone2)//計(jì)算兩個(gè)時(shí)區(qū)之間的時(shí)差,以分鐘為單位{ char*zone[32]={"UTC", "GMT","BST","IST","WET","WEST", "CET","CEST","EET","EEST","MSK", "MSD","AST","ADT","NST","NDT","EST","EDT","CST","CDT","MST","MDT","PST","PDT","HST","AKST","AKDT","AEST","AEDT","ACST","ACDT","AWST"}; floattime[32]={0,0,1,1,0,1,1,2,2,3,3,4,-4,-3,-3.5,-2.5,-5,-4,-6,-5,-7, -6,-8,-7,-10,-9,-8,10,11,9.5,10.5,8}; inti,j; for(i=0;strcmp(zone[i],zone1);i++);//找到第一個(gè)時(shí)區(qū)對(duì)應(yīng)的位置 for(j=0;strcmp(zone[j],zone2);j++);//找到第二個(gè)時(shí)區(qū)對(duì)應(yīng)的位置 return(int)((time[i]-time[j])*60);}intmain(){ intnCase; inti; //freopen("in.txt","r",stdin); scanf("%d",&nCase); for(i=0;i<nCase;i++) { chartime[9]; inthours,minutes; scanf("%s",time);//讀入時(shí)間 switch(time[0]) { case'n': hours=12;//輸入noon minutes=0; break; case'm': hours=0;//輸入midnight minutes=0; break; default: sscanf(time,"%d:%d",&hours,&minutes); hours%=12; scanf("%s",time); if(time[0]=='p') hours+=12; } chartimezone1[5],timezone2[5]; scanf("%s%s",timezone1,timezone2);//讀入時(shí)區(qū) intnewTime;//以分鐘為單位 newTime=hours*60+minutes+difference(timezone2,timezone1); if(newTime<0)newTime+=1440;//提前一天,將負(fù)的時(shí)間加上一天 newTime%=1440;//如果超過(guò)一天,將一天的時(shí)間減去 switch(newTime) { case0: printf("midnight\n"); break; case720: printf("noon\n"); break; default: hours=newTime/60; minutes=newTime%60; if(hours==0) printf("12:%02da.m.\n",minutes); elseif(hours<12) printf("%d:%02da.m.\n",hours,minutes); elseif(hours==12) printf("12:%02dp.m.\n",minutes); else printf("%d:%02dp.m.\n",hours%12,minutes); } } return0;}注意事項(xiàng):?jiǎn)栴}一:有人在處理時(shí)區(qū)名稱和時(shí)差的對(duì)應(yīng)關(guān)系時(shí),不會(huì)用數(shù)組元素及其下標(biāo)的方法處理,而是用一連串的ifelse語(yǔ)句逐一判定,造成代碼冗余,增大了出錯(cuò)的機(jī)會(huì);問(wèn)題二:對(duì)特殊時(shí)間點(diǎn)的表示有理解上的問(wèn)題。12:01am表示凌點(diǎn)1分,12:01pm表示中午12點(diǎn)1分;中午輸出noon,凌晨輸出midnight;問(wèn)題三:向前走了一天和推后了一天的情況沒(méi)考慮到。問(wèn)題四:將12小時(shí)制換算成24小時(shí)制,然后根據(jù)時(shí)區(qū)關(guān)系作時(shí)間變換,再由24小時(shí)制換算成12小時(shí)制,注意當(dāng)有半個(gè)小時(shí)的差別時(shí),分鐘的數(shù)值的調(diào)整最容易出錯(cuò)。CS46:不吉利的日期(來(lái)源:2723)問(wèn)題描述:在國(guó)外,每月的13號(hào)和每周的星期5都是不吉利的。特別是當(dāng)13號(hào)那天恰好是星期5時(shí),更不吉利。已知某年的一月一日是星期w,并且這一年一定不是閏年,求出這一年所有13號(hào)那天是星期5的月份,按從小到大的順序輸出月份數(shù)字。(w=1~7)輸入:輸入有一行,即一月一日星期幾(w)。(1<=w<=7)輸出:輸出有一到多行,每行一個(gè)月份,表示該月的13日是星期五。樣例輸入:7樣例輸出:110參考程序1(zzg):#include<stdio.h>intmain(){ intw;//讀入星期 intdays;//保存天數(shù) inti;//循環(huán)變量 intdates[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; while(scanf("%d",&w)!=EOF) { days=12; for(i=1;i<=12;i++)//依次遍歷每個(gè)月的13日 { days+=dates[i-1]; if((days+w)%7==5) printf("%d\n",i); } } return0;}#include<stdio.h>intmain(){intw,i,sum,m;sum=13;scanf("%d",&w);if(w<=5)m=5-w;elsem=12-w;inta[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};for(i=1;i<=13;i++){sum=sum+a[i-1];if(sum%7==m+1) printf("%d\n",i); }return0;}參考程序2(程穎宇):#include<stdio.h>intmain(){ constintMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31}; inti,Day; while(scanf("%d",&Day)!=EOF){ Day+=11;//本來(lái)加上12就是13號(hào)的星期幾的,但是這里用求余的辦法確定星期幾,也就是星期一是0,星期天是6,所以要減1 for(i=0;i<12;i++){ Day%=7; if(Day==4)printf("%d\n",i+1); Day+=Month[i]; } } return0;}CS47:特殊日歷計(jì)算(來(lái)源:2967)問(wèn)題描述:有一種特殊的日歷法,它的一天和我們現(xiàn)在用的日歷法的一天是一樣長(zhǎng)的。它每天有10個(gè)小時(shí),每個(gè)小時(shí)有100分鐘,每分鐘有100秒。10天算一周,10周算一個(gè)月,10個(gè)月算一年。現(xiàn)在要你編寫一個(gè)程序,將我們常用的日歷法的日期轉(zhuǎn)換成這種特殊的日歷表示法。這種日歷法的時(shí)、分、秒是從0開始計(jì)數(shù)的。日、月從1開始計(jì)數(shù),年從0開始計(jì)數(shù)。秒數(shù)為整數(shù)。假設(shè)0:0:01.1.2000等同于特殊日歷法的0:0:01.1.0。輸入:第一行是一個(gè)正整數(shù)N,表明下面有N組輸入。每組輸入有一行,格式如下:hour:minut

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論