【HNU 夏季程序设计】310.Maya历法


前言

文章仅分享一下个人的思路和可以在我们学校网站全通过的代码,如果有更好的思路欢迎评论分享。本人目前还是个菜鸟,代码写的并不优美,有需要注意的地方还请提出来呀! q(≧▽≦q)


一、问题描述

在学术休假期间,M.A. Ya教授在古老的Maya历法上有一个惊人的发现。从一个古老的令人棘手的信息中,教授发现Maya文明以365天为一年,称为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、1、2、3、4。玛雅人认为这个月是不吉利的,法院不开庭,贸易停止了,人们甚至停止清扫地板。

出于宗教的目的,Maya人使用另外一套历法,叫做Tzolkin(冬青年)。一年被分为13个期间,每个期间20天。每天被表示为由数字和日期名表示的数对。使用20个名字:imix、ik、akbal、kan、chicchan、cimi、manik、lamat、muluk、ok、chuen、eb、ben、ix、mem、cib、caban、eznab、canac、ahau,以及13个数字,双循环使用。

请注意,每一天都有一个明确的描述。例如,在年初的日子被描述如下:
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日历。

【输入形式】
在Haab中日期用以下形式表示:
NumberOfTheDay. Month Year
输入文件的第一行包含文件中输入日期的数目。接下来的n行包含Haab日历格式的n个日期,年份小于5000。

【输出形式】
Tzolkin日期用一下格式:
Number NameOfTheDay Year
输出包括n行,按照与输入日期对应的顺序,输出tzolkin日历格式日期。

【样例输入】
3
10.zac 0
0.pop 0
10.zac 1995
【样例输出】
3 chuen 0
1 imix 0
9 cimi 2801

二、思路分析

1.题意分析

题目解释Maya用两种历法来记录时间(每年365天):
其中第一种称为Haab,有19个月(pop、no、zip、zotz、tzec、xul、yoxkin、mol、chen、yax、zac、ceh、mac、kankin、muan、pax、koyab、cumhu),前18个月每月20天(0~19),最后一个月5天
(1~4),共计365天;


第二种称为Tzolkin,每年被分为13个期间(1~13),每个期间20天(imix、ik、akbal、kan、chicchan、cimi、manik、lamat、muluk、ok、chuen、eb、ben、ix、mem、cib、caban、eznab、canac、ahau),共计260天

2.解题策略

处理输入:样例输入格式为n个字符串,建议使用getline()输入,需要注意的是输入n之后要使用一次cin.ignore()忽略掉接下来的换行
解题:使用string中的substr(起点,长度)方法将输入的字符串的月、天、年分割开,从题意分析可以看出,第二种历法每次循环比第一次少105天,利用这点将其全部转换为天再除以260的到年份;
年份x105再求余260,加上月份x20再求余260,加上天数求余260即为余下的天数,那么天数求余13加1得到月份,天数求余20得到第二种历法的天数
(需要注意的是有乘和求余的时候,建议先求余再相乘,避免数据过大)

三、代码

//310.Maya历法
#include<bits/stdc++.h>
#include<string>
#include<map>
using namespace std;
int main()
{
	map<string,int>Haab;
	Haab["pop"]=0;
	Haab["no"]=1;
	Haab["zip"]=2;
	Haab["zotz"]=3;
	Haab["tzec"]=4;
	Haab["xul"]=5;
	Haab["yoxkin"]=6;
	Haab["mol"]=7;
	Haab["chen"]=8;
	Haab["yax"]=9;
	Haab["zac"]=10;
	Haab["ceh"]=11;
	Haab["mac"]=12;
	Haab["kankin"]=13;
	Haab["muan"]=14;
	Haab["pax"]=15;
	Haab["koyab"]=16;
	Haab["cumhu"]=17;
	Haab["uayet"]=18;
	string Tzolkin[20];
	Tzolkin[0]="imix";
	Tzolkin[1]="ik";
	Tzolkin[2]="akbal";
	Tzolkin[3]="kan";
	Tzolkin[4]="chicchan";
	Tzolkin[5]="cimi";
	Tzolkin[6]="manik";
	Tzolkin[7]="lamat";
	Tzolkin[8]="muluk";
	Tzolkin[9]="ok";
	Tzolkin[10]="chuen";
	Tzolkin[11]="eb";
	Tzolkin[12]="ben";
	Tzolkin[13]="ix";
	Tzolkin[14]="mem";
	Tzolkin[15]="cib";
	Tzolkin[16]="caban";
	Tzolkin[17]="eznab";
	Tzolkin[18]="canac";
	Tzolkin[19]="ahau";
	int n;
	cin>>n;
	string *str=new string[n];
	cin.ignore();
	for(int i=0;i<n;i++)
	{
		getline(cin,str[i]);
	}
	string s1,s2,s3;
	for(int i=0;i<n;i++)
	{
		s1=str[i].substr(0,str[i].find('.'));
		s2=str[i].substr(str[i].find('.')+1,str[i].find(' ')-str[i].find('.')-1);
		s3=str[i].substr(str[i].find(' ')+1);
		//cout<<s1<<s2<<s3<<endl;
		long long tem1=0,tem2=0;
		tem1=(105*stoi(s3,0,10)+Haab[s2]*20+stoi(s1))/260;
		tem2=105*(stoi(s3,0,10)%260)+Haab[s2]*20%260+stoi(s1)%260;
		cout<<tem2%13+1<<" "<<Tzolkin[tem2%20]<<" "<<tem1+stoi(s3,0,10)<<endl;
	}
	delete []str;
}

总结

使用map容器能够很好的将两个不同类型的数据联系起来,本题中利用其将数字与字符串的联系起来;使用getline()输入时,如果前面输入的有空格需要使用cin.ignore()先将其消除掉。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼树C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值