ACM1008瑪雅歷 剖析

原題如下:

上週末,M.A. Ya教授對古老的瑪雅有了一個重大發現。從一個古老的節繩(瑪雅人用於記事的工具)中,教授發現瑪雅人使用了一個一年有365天的叫做Haab的歷法。這個Haab曆法擁有19個月,在開始的18個月,一個月有20天,月份的名字分別是pop, no, zip, zotz, tzec, xul, yoxkin, mol, chen, yax, zac, ceh, mac, kankin, muan, pax, koyab, cumhu。這些月份中的日期用0到19表示。Haab歷的最後一個月叫做uayet,它只有5天,用0到4表示。瑪雅人認爲這個日期最少的月份是不吉利的,在這個月法庭不開庭,人們不從事交易,甚至沒有人打掃屋中的地板。

因爲宗教的原因,瑪雅人還使用了另一個曆法,在這個曆法中年被稱爲Tzolkin(holly年),一年被分成13個不同的時期,每個時期有20天,每一天用一個數字和一個單詞相組合的形式來表示。使用的數字是1~13,使用的單詞共有20個,它們分別是: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 ……也就是說數字和單詞各自獨立循環使用。

Haab歷和Tzolkin歷中的年都用數字0,1,……表示,數字0表示世界的開始。所以第一天被表示成:
Haab: 0. pop 0
Tzolkin: 1 imix 0
請幫助M.A. Ya教授寫一個程序可以把Haab歷轉化成Tzolkin歷。
Input

Haab歷中的數據由如下的方式表示:
日期. 月份 年數

輸入中的第一行表示要轉化的Haab歷日期的數據量。下面的每一行表示一個日期,年數小於5000。
Output

Tzolkin歷中的數據由如下的方式表示:
天數字 天名稱 年數

第一行表示輸出的日期數量。下面的每一行表示一個輸入數據中對應的Tzolkin歷中的日期。
Sample Input

3
10. zac 0
0. pop 0
10. zac 1995
Sample Output

3
3 chuen 0
1 imix 0
9 cimi 2801

解析

此題主要考查二維數組的使用,以及邏輯的判斷,熟練使用各種循環
由於月份的信息都是一個英文詞組,我們可以將兩個日曆中月信息分別存儲在兩個足夠長度的char數組中起名爲H_month[19][10],T_month[20][10],題目要求第一次輸入需要輸入的數據的組數,這裏只需將輸入的數字作爲for循環的循環變量控制循環次數即可。
接下來需要輸入Haab歷的year,_month, day三個數據,利用for循環,將_month的數據在H_month數組中的位置找出來,H_month的下標(記做j)就是所對應的月份,這樣就可以算出總天數,datas=365 * year + j*20 +day;
計算出總天數之後,Tzolkin的日期組成只是單詞和數字的組合,且兩個都按照自己的循環在進行(就像農曆的年份由天干地支兩個漢字組成,天干地支在下一年都會加1,且按照十天干十二地支的方法向下循環),所以這裏計算Tzolkin的日期只需要datas%13+1(日期) T_month[datas%20](月份),datas/260(第幾次出現這個日期,因爲每260天會有相同的日期出現)
具體代碼如下:

    #include<stdio.h>//瑪雅歷有兩種 第一種M_month是19個月,前18個月 20天 最後一個月5天
    #include<string.h>  
    int main()
    {
        const int namelen = 10;
        int i = 0, max;
        int j = 0;
        char M_month[19][namelen] = { "pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin", "mol", "chen", "yax", "koyab", "cumhu", "uayet" };
        char T_month[20][namelen]= { "imix", "ik", "akbal", "kan", "chicchan", "cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben", "ix", "mem", "cib", "caban", "eznab", "canac", "ahau" };
        scanf("%d",&max);//一共幾組日期
        for (i = 0; i <= max; i++)
        {
            int year, day, dates;
            char month[namelen];
            scanf("%d.%s %d", &day, month, &year);
            for (j = 0; j <= 19; j++)
            {
                if (!strcmp(M_month[j], month))
                break;
            }
        dates = 365 * year + j * 20 + day;//算出一共多少天,從0年0月0日開始
        printf("%d %s %d\n", 1 + dates % 13, T_month[dates % 20], dates / 260);//因爲month day 都是獨立的增長,直接取餘數
        }
    return 0;
    }

寫給看客:能看到這裏,代表你也是和我一樣剛剛開始刷acm的題庫,截止文章寫完(2017年3月25日),開始刷題一週,完成4道題,可能這個效率在大佬們看來效率很低,我以後也會像各位大佬一樣,效率慢慢變高,熱烈歡迎各位大佬提出建議。acm之路漫漫,希望自己在這個學期起碼能把10XX的題庫刷完吧↖(^ω^)↗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章