【TSOJ课程】20 1151 玛雅日历
課程29_20 1151 瑪雅日歷
題目:
題目描述:
上周末,M.A. Ya教授對(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表示。瑪雅人認(rèn)為這個(gè)日期最少的月份是不吉利的,在這個(gè)月法庭不開庭,人們不從事交易,甚至沒有人打掃屋中的地板。
因?yàn)樽诮痰脑?#xff0c;瑪雅人還使用了另一個(gè)歷法,在這個(gè)歷法中年被稱為Tzolkin(holly年),一年被分成13個(gè)不同的時(shí)期,每個(gè)時(shí)期有20天,每一天用一個(gè)數(shù)字和一個(gè)單詞相組合的形式來表示。使用的數(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。
注意:年中的每一天都有著明確唯一的描述,比如,在一年的開始,日期如下描述: 1 imix, 2 ik, 3 akbal, 4 kan, 5 chicchan, 6 cimi, 7 manik, 8 lamat, 9 muluk, 10 ok, 11 chuen, 12 eb, 13 ben, 1 ix, 2 mem, 3 cib, 4 caban, 5 eznab, 6 canac, 7 ahau, ,8 imix, 9 ik, 10 akbal ……也就是說數(shù)字和單詞各自獨(dú)立循環(huán)使用。
Haab歷和Tzolkin歷中的年都用數(shù)字0,1,……表示,數(shù)字0表示世界的開始。所以第一天被表示成:
Haab: 0 pop 0
Tzolkin: 1 imix 0
請(qǐng)幫助M.A. Ya教授寫一個(gè)程序可以把Haab歷轉(zhuǎn)化成Tzolkin歷。
輸入描述:
第一行表示要轉(zhuǎn)化的Haab 歷的數(shù)據(jù)量。下面的每一行表示一個(gè)日期。
Haab歷中的數(shù)據(jù)由如下的方式表示:日期 月份 年數(shù)。其中年數(shù)小于5000。
輸出描述:
每一行表示一個(gè)對(duì)應(yīng)的Tzolkin 歷日期。Tzolkin 歷中的數(shù)據(jù)由如下的方式表示: 天數(shù)字 天名稱 年數(shù)。
樣例輸入:
3
10 zac 0
0 pop 0
10 zac 1995
樣例輸出:
3 chuen 0
1 imix 0
9 cimi 2801
解析:
非常有意思的一道題,只要弄清楚了就會(huì)很簡(jiǎn)單。
題目講到了兩種歷法
-
第一種是類似公歷的歷法,叫Haab(哈勃)歷,每個(gè)月都是固定的20天,最后一個(gè)月是5天,一共365天。
需要注意的是日期是從0開始的,每個(gè)月的最后一天的日期是19。 -
第二種則是類似我國(guó)天干地支的歷法,叫Tzolkin(銼金)歷。由兩部分組成,前面那個(gè)部分每13個(gè)數(shù)字輪回一次,后面那個(gè)部分每20次輪回一次。
每過一天,兩個(gè)部分都會(huì)前進(jìn)一格,比如1 1的下一天是2 2。而兩個(gè)部分各不相干,比如13 13的下一天是1 14,7 20的下一天是8 1。
那么我們很快就會(huì)意識(shí)到,對(duì)于第二種,當(dāng)出現(xiàn)過一次1 1以后,下一次出現(xiàn)1 1的間隔就應(yīng)該是兩個(gè)輪回的最小公倍數(shù),13和20的最小公倍數(shù)是260,也就是說這種歷法的一年就是260天。
這種歷法很類似于天干地支,中國(guó)古代用天干地支記錄年份,天干有10個(gè),地支有12個(gè),所以古代年份是60一個(gè)輪回,所以“一甲子”就指的是60年,因?yàn)?0和12的最小公倍數(shù)是60。
扯遠(yuǎn)了,我們要做的是把用第一種歷法描述的日期轉(zhuǎn)化為第二種歷法的情況。
兩種歷法的月份名:
思路非常簡(jiǎn)單,首先求出距離Haab歷元年(0年pop月0日)的天數(shù),Haab歷的一年是365天,那么這個(gè)天數(shù)應(yīng)該等于year*365 + mon*20 + day,其中year、mon、day分別為年、月、日。
在這里需要注意:雖然Haab歷的最后一個(gè)月只有5天,但是其實(shí)我們不需要對(duì)它進(jìn)行特別處理,原因很簡(jiǎn)單:如果給出的是最后一個(gè)月的某一天,那么它距離本年年初的天數(shù)應(yīng)該是月份*20加上日期,而這個(gè)月究竟有幾天不會(huì)影響結(jié)果。
然后求Tzolkin歷。先求年,因?yàn)門zolkin歷一年是260天,所以我們把上面求出來的day整除掉260,就是年份了。
接著月份和日期的求法非常非常簡(jiǎn)單,因?yàn)樯厦嬲f過月份和日期兩個(gè)部分互不干擾的,比如過去了21天,那么月份就應(yīng)該是21余13=8,日期就是21余20=1。
解題:
代碼中的from_mondate是用來把Haab歷的某月某日轉(zhuǎn)化成此天到年初的時(shí)間。比如傳入(pop,1),就會(huì)返回1。因?yàn)槟瓿醯娜掌诰褪?,所以最后返回的部分其實(shí)是m*20 + date-0,然后-0被省略。
注意Tzolkin歷的日期是從1開始的,輸出時(shí)需要+1。
參考代碼:
// TSOJ-1151 瑪雅日歷 #include <iostream> #include <string> using namespace std;string tranha[] = {"pop","no","zip","zotz","tzec","xul","yoxkin","mol","chen","yax","zac","ceh","mac","kankin","muan","pax","koyab","cumhu","uayet"}; string trantz[] = {"imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok","chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"};int from_mondate(string smon, int date) {int m;for(int i=0;i<19;i++)if(smon == tranha[i]){m=i;break;}return m*20+date; }int main() {int date,year,n,day,nyear,nmon,ndate;string smon;cin>>n;for(;n--;){cin>>date>>smon>>year;day = year*365+from_mondate(smon, date);nyear = day/260;day %= 260;nmon = day%20;ndate = day%13;cout<<ndate+1<<' '<<trantz[nmon]<<' '<<nyear<<endl;}return 0; }總結(jié)
以上是生活随笔為你收集整理的【TSOJ课程】20 1151 玛雅日历的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国农业大学计算机专业在陕西录取分数线,
- 下一篇: 中国农业大学计算机考研复试分数线,202