将一个数转换成罗马数字,然后统计各个字母的个数。
罗马字母可以由两个字母组合而成,把这些字母手工生成放在一个表中称之为cell,然后每次减去一个
小于自身的最大的cell直到为0为止。
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
ifstream fin("preface.in");
ofstream fout("preface.out");
#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif
//code[i]为i的各个字母的个数
int code[3501][7];
bool visited[3501];
int result[7];
//最初的字母表
char alpha[] = { 'I','V','X','L','C','D','M'};
//cell表
char* cell[13] = {"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
//cell表对应的值
int cell_value[13] = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
//字母c在alpha表中的索引值
int get_num(char c)
{
for(int i=0;i<sizeof(alpha)/sizeof(char);++i)
if(alpha[i]==c) return i;
return -1;
}
//第一个小于n的cell的索引
int find_first_smaller(int n)
{
for(int i=12;i>=0;--i){
if(cell_value[i]<=n) return i;
}
}
void solve()
{
for(int i=0;i<13;++i){
visited[cell_value[i]]=true;
char *tmp = cell[i];
while(*tmp!=0){
code[cell_value[i]][get_num(*tmp)]++;
tmp++;
}
}
int n;
in>>n;
for(int i=1;i<=n;++i){
if(visited[i]){
for(int j=0;j<7;++j){
result[j]+=code[i][j];
}
}else{
int tmp = i;
while(tmp!=0&&!visited[tmp]){
int t = find_first_smaller(tmp);
for(int j=0;j<7;++j){
code[i][j]+=code[cell_value[t]][j];
}
tmp-=cell_value[t];
}
if(tmp!=0){
for(int j=0;j<7;++j)
code[i][j]+=code[tmp][j];
}
for(int j=0;j<7;++j)
result[j]+=code[i][j];
visited[i] = true;
}
}
for(int i=0;i<7;++i){
if(result[i]!=0){
out<<alpha[i]<<" "<<result[i]<<endl;
}
}
}
int main(int argc,char *argv[])
{
solve();
return 0;
}