题目链接:http://hihocoder.com/problemset/problem/1566
【中文题意】
1566 : 皇室成员的名字
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Ho正在学习世界历史。他发现历史上很多西方国家的皇室成员的名字都是由英文名字加罗马数字组成的,例如George IV(乔治四世)、William IV(威廉四世)、Elizabeth II(伊丽莎白二世)等。
为了更好的梳理历史脉络,小Ho决定写个程序把历史书上出现过的皇室名字排序:首先按英文名字的字典序排序,如果英文名字相同,再按罗马数字从小到大的顺序排序。
罗马数字表示可以参考 https://en.wikipedia.org/wiki/Roman_numerals 中的”standard forms”。
输入
第一行包含一个整数N,表示名字的总数。
以下N行每行包含一个名字。英文名字与罗马数字之间由一个空格隔开。其中英文名字首字母是大写字母,其余字母是小写字母。
对于100%的数据,1 ≤ N ≤ 100000, 罗马数字 < 4000
输出
输出N行,每行一个名字。
样例输入
5
Elizabeth II
Elizabeth C
William IV
Hiho MMXVII
Hiho MMXVII
样例输出
Elizabeth II
Elizabeth C
Hiho MMXVII
Hiho MMXVII
William IV
【思路分析】将罗马数字转化为正常的数字,然后结构体排序就好了。
【AC代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
using namespace std;
struct node
{
char name[20];
char s[20];
int val;
}Peo[100005];
char str[10]="IVXLCDM";
int num[10]={1,5,10,50,100,500,1000};
bool cmp(node x,node y)
{
if(strcmp(x.name,y.name)==0)
{
return x.val<y.val;
}
else
{
return strcmp(x.name,y.name)<0;
}
}
int tran(char *s)
{
int len=strlen(s);
int cnt=0,a[20];
for(int i=0; i<len; i++)
{
int f=0,t;
if(s[i]==s[i+1]&&i!=len-1)
{
if(s[i]==s[i+2]&&i!=len-2)
{
f=2;
}
else
f=1;
}
for(int k=0; k<7; k++)
if(s[i]==str[k])
{
t=k;
break;
}
a[cnt++]=num[t]*(f+1);
i+=f;
}
int sum=0;
for(int i=0; i<cnt; i++)
sum+=a[i];
for(int i=0; i<cnt-1; i++)
{
if(a[i]<a[i+1])sum-=2*a[i];
}
return sum;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{
scanf("%s %s",&Peo[i].name,&Peo[i].s);
Peo[i].val=tran(Peo[i].s);
}
sort(Peo,Peo+n,cmp);
for(int i=0;i<n;i++)
{
printf("%s %s\n",Peo[i].name,Peo[i].s);
}
}
return 0;
}