USACO-Preface Numbering

http://ace.delos.com/usacoprob2?a=tOdxUub2T3T&S=preface

这题最简单的是直接枚举。

当然,你可以用数学的方法分析求解,你甚至可以用打表的方法= =

这题麻烦的地方在于如何把一个数准确的转变成那些字符。

把数字直接拆分,然后统计。比如说:

对于439,把它拆分成400+30+9,就是:CD+XXX+IX

对于498,拆分成400+90+8,就是:CD+XC+VIII

统计的就不说了

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;

const string number[4][9]={{"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 f[100]={0};
int d[10]={0};
int n,sum=0;

void work(int x)        //拆分数字,注意到d是由个位开始存的
{
    d[0]=0;
    while (x>0)
    {
        d[++d[0]]=x%10;
        x/=10;
    }
}

void work1()
{
    for (int i=1;i<=d[0];i++)
    if (d[i])   //考虑到d[i]==0时不会对结果产生影响
    {
        for (int j=0;number[i-1][d[i]-1][j];j++)     //这里直接累加就是了
            f[number[i-1][d[i]-1][j]]++;
    }
}

int main()
{
    freopen("preface.in","r",stdin);
    freopen("preface.out","w",stdout);
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        work(i);
        work1();
    }
    //输出这里别被坑了,顺序不是说字母表顺序,而是数字的大小顺序
    if (f['I']) cout<<"I "<<f['I']<<endl;
    if (f['V']) cout<<"V "<<f['V']<<endl;
    if (f['X']) cout<<"X "<<f['X']<<endl;
    if (f['L']) cout<<"L "<<f['L']<<endl;
    if (f['C']) cout<<"C "<<f['C']<<endl;
    if (f['D']) cout<<"D "<<f['D']<<endl;
    if (f['M']) cout<<"M "<<f['M']<<endl;
    return 0;
}

当然,我这里为了简洁,f数组直接用字符表示,你也可以开一个f[7]的数组,不过work1函数中的转换过程就稍微麻烦些。

转载于:https://www.cnblogs.com/ay27/archive/2012/10/25/2740025.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值