USACO-Section 2.2 Preface Numbering(数学)
3199 ワード
説明
一種類の本の序言はローマ数字でページ番号をつけたものだ.従来のローマ数字は、特定の数値を単一のアルファベットで表しています.以下は標準数字表です.
最大3つの同じ10 nとして表すことができる数字(I,X,C,M)は、それらの和を表すために連続的に一緒に置くことができる.
5 x 10 nと表すことができる文字(V,L,D)は連続して現れない.
次のルールに加えて、一般的には、文字は減算順に連続して表示されます.
場合によっては、10 nと表すことができる数が、それより1または2大きい数の前に現れる(IはVまたはXの前にあり、XはLまたはCの前にあるなど).この場合、数値は後の数に等しく、前の数を減算します.
This compound mark forms a unit and may not be combined to make another compound mark (e.g., IXL is wrong for 39; XXXIX is correct).
XD、IC、XMのような表現は違法です.前の数は後ろの数よりずっと小さいからです.XD(490の誤った表現)については、CDXCと書くことができる.IC(99の誤った表現)については、XCIXと書くことができる.XM(990の誤った表現)については、CMXCと書くことができる.90 is expressed XC and not LXL, since L followed by X connotes that successive marks are X or smaller (probably, anyway).
N(1<=N<3500)、序文のページ番号を指定します.1ページ目からNページ目まで、Iがいくつ、Vがいくつ、など(小さい順)を集計してください.表示されていない文字は出力しないでください.
例えばN=5であると,ページ番号は,I,II,III,IV,V.の合計7個のIが出現し,2個のVが出現する.
書式設定
PROGRAM NAME: preface
INPUT FORMAT:
(preface.in)
整数N.
OUTPUT FORMAT:
(preface.out)
各行に1つの文字と1つの数字kがあり、この文字がk回現れたことを示す.文字は、数値テーブルの増分順に出力する必要があります.
SAMPLE INPUT
SAMPLE OUTPUT
こんなに简単な问题をすぐに作ることができなくて、长い间、列挙の方法があるのに数学の方法を使わなければなりません..
スタートアルゴリズムが合っているかもしれませんが、下付き境界と負数を処理するのを忘れた場合、結果はずっと間違っています.の
一種類の本の序言はローマ数字でページ番号をつけたものだ.従来のローマ数字は、特定の数値を単一のアルファベットで表しています.以下は標準数字表です.
I 1 L 50 M 1000
V 5 C 100
X 10 D 500
最大3つの同じ10 nとして表すことができる数字(I,X,C,M)は、それらの和を表すために連続的に一緒に置くことができる.
III=3
CCC=300
5 x 10 nと表すことができる文字(V,L,D)は連続して現れない.
次のルールに加えて、一般的には、文字は減算順に連続して表示されます.
CCLXVIII = 100+100+50+10+5+1+1+1 = 268
場合によっては、10 nと表すことができる数が、それより1または2大きい数の前に現れる(IはVまたはXの前にあり、XはLまたはCの前にあるなど).この場合、数値は後の数に等しく、前の数を減算します.
IV = 4
IX = 9
XL = 40
This compound mark forms a unit and may not be combined to make another compound mark (e.g., IXL is wrong for 39; XXXIX is correct).
XD、IC、XMのような表現は違法です.前の数は後ろの数よりずっと小さいからです.XD(490の誤った表現)については、CDXCと書くことができる.IC(99の誤った表現)については、XCIXと書くことができる.XM(990の誤った表現)については、CMXCと書くことができる.90 is expressed XC and not LXL, since L followed by X connotes that successive marks are X or smaller (probably, anyway).
N(1<=N<3500)、序文のページ番号を指定します.1ページ目からNページ目まで、Iがいくつ、Vがいくつ、など(小さい順)を集計してください.表示されていない文字は出力しないでください.
例えばN=5であると,ページ番号は,I,II,III,IV,V.の合計7個のIが出現し,2個のVが出現する.
書式設定
PROGRAM NAME: preface
INPUT FORMAT:
(preface.in)
整数N.
OUTPUT FORMAT:
(preface.out)
各行に1つの文字と1つの数字kがあり、この文字がk回現れたことを示す.文字は、数値テーブルの増分順に出力する必要があります.
SAMPLE INPUT
5
SAMPLE OUTPUT
I 7
V 2
こんなに简単な问题をすぐに作ることができなくて、长い间、列挙の方法があるのに数学の方法を使わなければなりません..
スタートアルゴリズムが合っているかもしれませんが、下付き境界と負数を処理するのを忘れた場合、結果はずっと間違っています.の
/*
ID: your_id_here
PROG: preface
LANG: C++
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int nn[3][10]={0,1,2,3,1,0,1,2,3,1,
0,0,0,0,1,1,1,1,1,0,
0,0,0,0,0,0,0,0,0,1};
const int nm[3][10]={0,1,3,6,7,7,8,10,13,14,
0,0,0,0,1,2,3,4,5,5,
0,0,0,0,0,0,0,0,0,1};
int n,num[11],t,t1,t2,tt,tp;//num , ,OJ ...
char ch[8]="IVXLCDM";
int main() {
int i;
freopen("preface.in","r",stdin);
freopen("preface.out","w",stdout);
while(1==scanf("%d",&n)) {
for(i=0;i<8;++i)
num[i]=0;
i=0,tp=1,tt=1,t=n;
while(t) {
t1=t/10;
tt=t%10-1;
if(tt==-1)// , tt -1 0
tt=0;
// : abc
//Ⅰ:
//①ab( c ) 0~9 ②1 0~c-1 ③n%tp+1( c +1=0+1) c
//Ⅱ:
//①a( b ) 0~9 ②1 0~b-1 ③n%tp+1( b +1=b+1) b
//Ⅲ:
//①0( a ) 0~9 ②1 0~a-1 ③n%tp+1( b +1=a+1) a
num[i]+=t1*nm[0][9]*tp+nm[0][tt]*tp+(n%tp+1)*nn[0][t%10];
num[i+1]+=t1*nm[1][9]*tp+nm[1][tt]*tp+(n%tp+1)*nn[1][t%10];
num[i+2]+=t1*nm[2][9]*tp+nm[2][tt]*tp+(n%tp+1)*nn[2][t%10];
t=t1;
i+=2;
tp*=10;
}
i=0;
while(num[i]) {
printf("%c %d
",ch[i],num[i]);
++i;
}
}
return 0;
}