USACO-Section2.2 Preface Numbering

2017-8-30

题目描述

序言的页码数,请统计在第1页到第N页中,有几个I出现,几个V出现...

解答

将已知存起来,不再重复计算,没有求的用已经求好的加起来

代码

/*
ID: 18795871
PROG: preface
LANG: C++
*/
#include<iostream>
#include<fstream> 
#include<cstring>
using namespace std;
const int N = 3500;

ifstream fin("preface.in");
ofstream fout("preface.out");

string x[N+1];
bool f[N+1]; //避免重复计算 
int cnt[7];
char y[7]={'I','V','X','L','C','D','M'};
int n;

void init(){
   int i;
   x[1]="I";x[10]="X";x[100]="C";x[1000]="M";
   x[5]="V";x[50]="L";x[500]="D";
   x[2]="II";x[20]="XX";x[200]="CC";x[2000]="MM";
   x[3]="III";x[30]="XXX";x[300]="CCC";x[3000]="MMM";
   x[4]="IV";x[40]="XL";x[400]="CD";
   x[6]="VI";x[60]="LX";x[600]="DC";
   x[7]="VII";x[70]="LXX";x[700]="DCC";
   x[8]="VIII";x[80]="LXXX";x[800]="DCCC";
   x[9]="IX";x[90]="XC";x[900]="CM";
   for (int i=1;i<=10;i++){
         f[i]=true;
         f[i*10]=true;
         f[i*100]=true;
   }
   f[2000]=true;
   f[3000]=true;
}

void cal(int m){
    if (f[m]) return ;
    f[m]=true; 
    if (m<100){
        int s=m/10;
        int g=m%10;
        x[m]=x[s*10]+x[g];
    }else if (m<1000){
        int b=m/100;
        x[m]=x[b*100]+x[m-b*100];
    }else{
        int q=m/1000;
        x[m]=x[q*1000]+x[m-q*1000];
    }
    return ;
}

int main(){
    fin>>n;
    int i,j;
    init();
    memset(f,false,sizeof(f));
    for (i=1;i<=n;i++){
        cal(i);
    }
    for (i=1;i<=n;i++){
        for (j=0;j<=x[i].length();j++){
            switch(x[i][j]){
                case 'I':
                    cnt[0]++;break;
                case 'V':
                    cnt[1]++;break;
                case 'X':
                    cnt[2]++;break;
                case 'L':
                    cnt[3]++;break;
                case 'C':
                    cnt[4]++;break;
                case 'D':
                    cnt[5]++;break;
                case 'M':
                    cnt[6]++;break;
            }
        }
    } 
    for (i=0;i<7;i++){
        if (cnt[i]){
            fout<<y[i]<<" "<<cnt[i]<<endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值