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