前言
文章仅分享一下个人的思路和可以在我们学校网站全通过的代码,如果有更好的思路欢迎评论分享。本人目前还是个菜鸟,代码写的并不优美,有需要注意的地方还请提出来呀! 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()先将其消除掉。