题目描述
一类书的序言是以罗马数字标页码的。传统罗马数字用单个字母表示特定的数值,以下是标准数字表:
I 1 V 5 X 10 L 50 C 100 D 500 M 1000
最多3个同样的可以表示为10n的数字(I,X,C,M)可以连续放在一起,表示它们的和:
III=3 CCC=300
可表示为5x10n的字符(V,L,D)从不连续出现。
除了下一个规则,一般来说,字符以递减的顺序接连出现:
CCLXVIII = 100+100+50+10+5+1+1+1 = 268
有时,一个可表示为10n的数出现在一个比它大1级或2级的数前(I在V或X前面,X在L或C前面,等等)。在这种情况下,数值等于后面的那个数减去前面的那个数:
IV = 4 IX = 9 XL = 40
一个数 用罗马数字来表示 有且仅有一种 而且不能复合嵌套使用(比如I是1 X是10 有人可能要说 IXL就能表示50-10-1 但是IXL绝对不能用来表达39 ) (那么39用什么来表示呢 XXXIX是唯一 而且正确的选择- -)
像XD, IC, 和XM这样的表达是非法的,因为前面的数比后面的数小太多。对于XD(490的错误表达),可以写成 CDXC; 对于IC(99的错误表达),可以写成XCIX; 对于XM(990的错误表达),可以写成CMXC。 90 写成 XC 而不是 LXL, 因为 L 后面的 X 意味着后继标记是 X 或者更小 (不管怎样,可能吧)(等同于阿拉伯数字 每位 数字分别表示)。
给定N(1 <= N < 3,500), 序言的页码数,请统计在第1页到第N页中,有几个I出现,几个V出现,等等 (从小到大的顺序)。不要输出没有出现过的字符。
比如N = 5, 那么页码数为: I, II, III, IV, V. 总共有7个I出现,2个V出现。
输入输出格式
输入格式:
一个整数N。
输出格式:
每行一个字符和一个数字k,表示这个字符出现了k次。字符必须按数字表中的递增顺序输出。
输入输出样例
输入样例#1:
5
输出样例#1:
I 7 V 2
说明
翻译来自NOCOW
USACO 2.2
题意:
罗马数字和阿拉伯数字直接可以互相转换,给出一个阿拉伯数字N,计算从1-N这些数直接有多少个 IVXLCDM这些字符。
题意比较难理解,先列出一些罗马数字和阿拉伯数字的对照
1
I
2
II
3
III
4
IV
5
V
6
VI
7
VII
8
VIII
9
IX
10
X
11
XI
12
XII
13
XIII
14
XIV
15
XV
16
XVI
17
XVII
18
XVIII
19
XIX
20
XX
21
XXI
22
XXII
23
XXIII
24
XXIV
25
XXV
26
XXVI
27
XXVII
28
XXVIII
29
XXIX
30
XXX
31
XXXI
32
XXXII
33
XXXII
34
XXXIV
35
XXXV
36
XXXVI
37
XXXVII
38
XXXVIII
39
XXXIX
40
XL
不难发现一个多位数的由每个1-10和十的倍数的数拼接组成。比如29是XXIX,那么9是IX,20是XX。这样就可以先列出1-10的数,然后递推打表。
下面谁是我自己找的1-30的数据。
AC代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
const int MOD=int(1e9)+7;
using namespace std;
int i,j,k,l;
int cnt[10];
char str[]=" IVXLCDM";
int cunt[4][3]={
{1, 2, 3},
{3, 4 ,5},
{5, 6 ,7},
{7, 0, 0}
};//N最大是四位数,所以只要四组
int Roma[10][3]={
{0,0,0},{1,0,0},{2,0,0},{3,0,0},
{1,1,0},{0,1,0},{1,1,0},{2,1,0},{3,1,0},
{1,0,1}
};
void mix(int x)
{
for(int i=0;x;i++,x/=10)
{
int j=x%10;
for(int k=0;k<3;k++)
cnt[cunt[i][k]]+=Roma[j][k];
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
mix(i);
for(int i=1; i<=7; i++)
if(cnt[i])
cout<<str[i]<<' '<<cnt[i]<<endl;
}
return 0;
}