USACO 2.2 Preface Numbering

USACO 2.2 Preface Numbering


将一个数转换成罗马数字,然后统计各个字母的个数。

罗马字母可以由两个字母组合而成,把这些字母手工生成放在一个表中称之为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 ;
}


你可能感兴趣的:(USACO 2.2 Preface Numbering)