1. 程式人生 > >【搜尋】洛谷 P1465 序言頁碼 Preface Numbering

【搜尋】洛谷 P1465 序言頁碼 Preface Numbering

題目描述

一類書的序言是以羅馬數字標頁碼的。傳統羅馬數字用單個字母表示特定的數值,以下是標準數字表:

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

程式碼

#include<iostream>
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n; int ans[250]; string page[50]={" ","I","II","III","IV","V","VI","VII","VIII","IX","X","XX","XXX","XL","L","LX","LXX","LXXX","XC","C","CC","CCC","CD","D","DC","DCC","DCCC","CM","M","MM","MMM"}; int counts[50]={0,1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900,1000,2000,3000}; void read(int &x) { x=0; char c=getchar(); while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } } int main() { read(n); for(int i=1;i<=n;++i) { int temp=i,k=30; while(counts[k]>temp)k--; for(int j=k;j>=1;--j) { if(temp>=counts[j]) { temp-=counts[j]; for(int t=0;t<page[j].size();++t)ans[page[j][t]]++; } if(temp==0)break; } } int c; c='I'; if(ans[c]!=0)printf("I %d\n",ans[c]); c='V'; if(ans[c]!=0)printf("V %d\n",ans[c]); c='X'; if(ans[c]!=0)printf("X %d\n",ans[c]); c='L'; if(ans[c]!=0)printf("L %d\n",ans[c]); c='C'; if(ans[c]!=0)printf("C %d\n",ans[c]); c='D'; if(ans[c]!=0)printf("D %d\n",ans[c]); c='M'; if(ans[c]!=0)printf("M %d\n",ans[c]); return 0; }