POJ 1008 玛雅日历

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 72250 Accepted: 22225

描述

玛雅文明使用365天的年历,称为Haab历法,有19个月,前18个月都是20天,月名为: pop, no, zip, zotz, tzec, xul, yoxkin, mol, chen, yax, zac, ceh, mac, kankin, muan, pax, koyab, cumhu.不考虑月名,每个月中,每天标记为0,1,… , 19.Haab的最后一个月称为uayet ,每天标记为0,1,2,3,4。玛雅人相信这个月是不幸的。

出于宗教目的,玛雅使用另一种日历,一年称为Tzolkin (holly year)。一年被分为13个区间,每个区间20天。每天被标记为(day_number,day_name)使用13个day_number(数字1~13)和20个day_name分别为: imix, ik, akbal, kan, chicchan, cimi, manik, lamat, muluk, ok, chuen, eb, ben, ix, mem, cib, caban, eznab, canac, ahau ;(day_number和day_name同时循环)

请注意每一天都有明确的描述,例如:
在年初具有如下表示:
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, 继续进入下个20循环 8 imix, 9 ik, 10 akbal …

在Haab和Tzolkin的中,年都被数组0,1,…,标记,数字0是世界的开始。因此,第一天是:
Haab: 0. pop 0
Tzolkin: 1 imix 0
编写一个程序,将日期从Haab转换为Tzolkin

输入

Haab日期输入的格式:NumberOfTheDay. Month Year
第一行是输入的日期的个数,之后的n行包含n个Haab日期,输入的年小于5000.

输出

Tzolkin日期输出的格式:Number NameOfTheDay Year
第一行是输出的日期的个数,之后的n行包含n个Tzolkin日期,输出的顺序对应输入的日期

输入样例

3
10. zac 0
0. pop 0
10. zac 1995

输出样例

3
3 chuen 0
1 imix 0
9 cimi 2801

思路:

从世界开始时经历的总天数sumday
sumday=年*365+月份*20+日+1,
其中,
年:是输入的年份,因为从0开始计数,所以已经默认减去1
月份:由于存在数组中,数组的下表从0开始计数,所以已经默认减去1
日:由于输入的日从0开始计数,所以应该+1则为真实的天数
结果的天数是sumday%13,如果结果为0则输出13(Tzolkin的13循环从1开始计数)
结果的天名是sumday%20,如果结果为0则对应的是第20天,只要处理一下天名的数组,将第20天放在下标0处即可。
结果的年份是sumday/260,注意!是当给出的sumday恰好是260时,输出年份是0年,此时正确,但如果是是260的2倍或者以上倍数,即:
sumday == x*260 (x>1, x为整数),
则输出年份应为x-1。
所以经过统一的处理:输出的Tzolkin日历的年份应为:
(sumday-1)/260

c++实现

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;

const char hmonth[19][10] = {
    "pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin",
    "mol", "chen", "yax", "zac", "ceh", "mac", "kankin",
    "muan", "pax", "koyab", "cumhu","uayet"};
const char tzday[20][10] = { "ahau","imix", "ik", "akbal", "kan",
    "chicchan", "cimi", "manik", "lamat", "muluk", "ok",
    "chuen", "eb", "ben", "ix", "mem", "cib", "caban",
    "eznab", "canac"};//把第20天放在第0个位置,因为取余运算结果为0时表示第20天
int find_month(char* month){
    for(int i = 0; i <20; i++){
        if(!strcmp(month, hmonth[i])){
            return i;//hmonth在数组中从0开始计数
        }
    }
    return -1;
}


int main()
{
    int ncase;
    cin >> ncase;
    cout << ncase << endl;
    int day,year;
    char month[10];//存放月份名

    for(int i = 0; i < ncase; i++){
        scanf("%d. %s %d", &day, &month, &year);
        int imonth = find_month(month);//月份对应的数字已经减去1
        int sumday = year*365+imonth*20+day+1;//day从0开始计数
        int tyear = (sumday-1)/260;//当年份为260的2倍及以上整数倍时,不-1则输出多了1年
        int tday = sumday%13;
        if(tday==0)
            tday=13;
        int tmonth = sumday%20;
        cout<< tday << " " << tzday[tmonth] << " " << tyear << endl;
    }
    return 0;
}

参考

http://blog.csdn.net/shaw1994/article/details/12308965
http://www.cnblogs.com/ay27/archive/2013/02/24/2924012.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值