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函数中的转换过程就稍微麻烦些。

posted @ 2012-10-25 19:57  ay27  阅读(138)  评论(0编辑  收藏  举报