• 罗马数字


    Problem description

      一类书的序言是以罗马数字标页码的。传统罗马数字用单个字母表示特定的数值,一下是标准数字表:

      I 1 L 50 M 1000
      V 5 C 100
      X 10 D 500

      最多3个可以表示为10n的数字(I,X,C,M)可以连续放在一起,表示它们的和:

      III=3
      CCC=300
      可表示为5x10n的字符(V,L,D)从不连续出现。

      除了下一个规则,一般来说,字符以递减的顺序接连出现:

      CCLXVIII = 100+100+50+10+5+1+1+1 = 268
      有时,一个可表示为10^n的数出现在一个比它大的数前(I在V或X前面,X在L或C前面,等等)。在这种情况下,数值等于后面的那个数减去前面的那个数:

      IV = 4
      IX = 9
      XL = 40
      像XD, IC, 和XM这样的表达是非法的,因为前面的数比后面的数小太多。对于XD(490的错误表达),可以写成 CDXC; 对于IC(99的错误表达),可以写成XCIX; 对于XM(990的错误表达),可以写成CMXC。

      给定N(1 <= N < 3,500), 序言的页码数,请统计在第1页到第N也中,有几个I出现,几个V出现,等等 (从小到大的顺序)。不要输出并没有出现过的字符。

      比如N = 5, 那么页码数为: I, II, III, IV, V. 总共有7个I出现,2个V出现。

    Input format

    一个整数N。

    Output format

    每行一个字符和一个数字k,表示这个字符出现了k次。字符必须按数字表中的递增顺序输出。

    Algorithm design

     Simple enumeration

    Problem analysis

    优化后:

    针对大量的重复运算

    按位数分三种情况处理即可

    Source code

     1 #include <bits/stdc++.h>
     2 #define F(i,j,k) for(int i=j;i<=k;i++)
     3 #define D(i,j,k) for(int i=j;i>=k;i--)
     4  
     5 using namespace std;
     6  
     7 string let="IVXLCDM";
     8  
     9 int cnt,cnt_let[7];
    10  
    11 void input()
    12 {
    13    cin>>cnt;
    14    return;
    15 }
    16  
    17 void work()
    18 {
    19    F(turn,1,cnt)
    20    {
    21       int num=turn;
    22       int lvl_chk=0;
    23       while(num)
    24       {
    25          int num_chk=num%10;
    26          if(num_chk<=3)
    27             cnt_let[lvl_chk]+=num_chk;
    28          else if(num_chk<=8)
    29          {
    30             cnt_let[lvl_chk]+=abs(num_chk-5);
    31             cnt_let[lvl_chk+1]+=1;
    32          }
    33          else
    34          {
    35             cnt_let[lvl_chk]+=1;
    36             cnt_let[lvl_chk+2]+=1;
    37          }
    38          lvl_chk+=2;
    39          num/=10;
    40       }
    41    }
    42    return;
    43 }
    44  
    45 void output()
    46 {
    47    F(i,0,6)
    48       if(cnt_let[i])cout<<let[i]<<" "<<cnt_let[i]<<endl;
    49    return;
    50 }
    51  
    52 int main()
    53 {
    54    freopen("preface.in","r",stdin);
    55    freopen("preface.out","w",stdout);
    56    input();
    57    work();
    58    output();
    59    return 0;
    60 }
    61  
    View Code

    over

  • 相关阅读:
    有关远程设置的问题
    QT使用tableWidget显示双排列表 而且选中用红框圈出来
    一个程序猿的跨洋找工作分享
    linux块设备的IO调度算法和回写机制
    基于servlet实现一个web框架
    Java中的条件编译(转)
    Android NDK 使用第三方静态库(转)
    Android 使用动态库或静态库来编译生成动态库(转)
    Android应用运行过程(转)
    android NDK编译(导入).a文件和编译多个so文件(转)
  • 原文地址:https://www.cnblogs.com/qswx/p/9155666.html
Copyright © 2020-2023  润新知