QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 843|回复: 5

再来一题[ACM Asian 1995 Problem F]

[复制链接]
发表于 2003-10-22 19:01:41 | 显示全部楼层 |阅读模式
希望这次不会有人因为题目简单而不屑动手

The Twentieth Annual International Collegiate Programming Contest

Problem F: Roman Numbers
Input File: jtd6.dat

Write a program to convert positive integers into Roman numbers. Assume that the numbers to be converted is less than 5000. The rule for constructing a Roman number is assumed to be as follows. In Roman number system, i is the symbol for 1, v for 5, x for 10, l for 50, c for 100, d for 500 and m for 1000. Symbols with larger values usually appear before symbols with smaller values. The value of a Roman number is, in general, the sum of the values of the symbols. For example, ii is 2, viii is 8. However, if a symbol with smaller value appears before a symbol with larger value, the value of these two symbols is the difference of the two values. For example, iv is 4, ix is 9, and lix is 59. Note that no four consecutive symbols in the Roman number can be the same. For example, iv, but not iiii, is the Roamn number 4. The Roman numbers contructed in this way may not be unique. For example, both mcmxc and mxm are valid for 1990. Although the roman number generated by your program need not be the shortest one, never use vv for 10, ll for 100, dd for 1000, or vvv for 15, etc.

Input
The input data is stored in a file. Each record of the input file contains one positive integer x. You may assume that x is less than 5000.

Output
For each number of the input file, print the number in decimal and its Roman form.

Sample Input
3
8
172
4
1990
5
Sample Output
3      iii
8      viii
172    clxxii
4      iv
1990   mcmxc
5      v
 楼主| 发表于 2003-10-22 22:02:14 | 显示全部楼层
小弟我没有电脑,烦各位调试一下
[code:1]
#include <stdio.h>

typedef struct{
     int value;      /*数值*/
     int degree;   /*数位 3千位  2百位  1十位  0个位*/
}NUM;

typedef struct{
     char roman[4];
}RESULT;

NUM num[4];
RESULT res[4];

/*计算a的n次方*/
int asn(int a, int n)
{
     /*因为只需要最大为3次方,所以直接用乘了:P*/
     if(n==3) return a*a*a;
     else if(n==2) return a*a;
     else return a;
}

int Input(NUM *num)
{
     int i=0;
     int n=0;
     do{
          printf("Input the number(<5000).  ");
          scanf(" %d", &n);
     } while(n>=5000);

     for(i=3; i>=0; i--){
           num[i].value=n/asn(10,i);
           num[i].degree=i;
           n%=asn(10,i);
     }
     return 1;
}

int Output(RESULT *res)
{
     int i, j;
     for(i=3; i>=0; i--)
          for(j=0; j<4; j++){
               if(res[i].roman[j]=='\0') break;
               printf("%c",res[i].roman[j]);
          }
     return 1;
}

void Trans(NUM *num, RESULT *res)
{
     int i=0;
     int d=0;
     for(i=3; i>=0; i--){
          switch(d=num[i].degree){
                case 3:
                            for(i=0; i<num[d].value; i++)
                                  res[d].roman[i]='m';
                            break;
                case 2:
                            /*这是一段极其丑陋的程序,不过,时间太紧,凑或着看吧*/
                            if(num[d].value==9){
                                   res[d].roman[0]='c';
                                   res[d].roman[1]='m';
                            }
                            else if(num[d].value==4){
                                   res[d].roman[0]='c';
                                   res[d].roman[1]='d';
                            }
                            else if(num[d].value==5)
                                   res[d].roman[0]='d';
                            else if(num[d].value<=3)
                                   for(i=0; i<num[d].value; i++)
                                         res[d].roman[i]='c';
                            else{
                                   res[d].roman[0]='d';
                                   for(i=0; i<num[d].value-5; i++)
                                         res[d].roman[i+1]='c';
                            }
                            break;
                case 1:
                            if(num[d].value==9){
                                   res[d].roman[0]='x';
                                   res[d].roman[1]='c';
                            }
                            else if(num[d].value==4){
                                   res[d].roman[0]='x';
                                   res[d].roman[1]='l';
                            }
                            else if(num[d].value==5)
                                   res[d].roman[0]='l';
                            else if(num[d].value<=3)
                                   for(i=0; i<num[d].value; i++)
                                         res[d].roman[i]='x';
                            else{
                                   res[d].roman[0]='l';
                                   for(i=0; i<num[d].value-5; i++)
                                         res[d].roman[i+1]='x';
                            }
                            break;
                 case 0:
                            if(num[d].value==9){
                                   res[d].roman[0]='i';
                                   res[d].roman[1]='x';
                            }
                            else if(num[d].value==4){
                                   res[d].roman[0]='i';
                                   res[d].roman[1]='v';
                            }
                            else if(num[d].value==5)
                                   res[d].roman[0]='v';
                            else if(num[d].value<=3)
                                   for(i=0; i<num[d].value; i++)
                                         res[d].roman[i]='i';
                            else{
                                   res[d].roman[0]='v';
                                   for(i=0; i<num[d].value-5; i++)
                                         res[d].roman[i+1]='i';
                            }
                            break;
                   default:
                            printf("some error:P\n");
                            break;
        }/*end switch*/
    }/*end for*/
}
/*case语句中的转换过程应该可以通过函数表达,那样的话会更清晰也更合理
*不想写了,而且反正也调试不了,热情大减啊
*考研实在是太累了........
*/

int main(int argc, char** argv){
     Input(num);
     Trans(num,res);
     Output(res);
     return 1;
}

/*如果真的有很多错误的话,千万别怪我...............*/
     
[/code:1]


回复

使用道具 举报

发表于 2003-10-22 22:38:42 | 显示全部楼层
至少我不是应为冒泡简单才没冒,因为我一直觉得那些排序算法很麻烦,经常让我的大脑运行出错,所以就不做了~   
回复

使用道具 举报

 楼主| 发表于 2003-10-23 12:32:33 | 显示全部楼层
哈~哈哈~哈哈哈~~
回复

使用道具 举报

发表于 2003-10-23 15:40:22 | 显示全部楼层
doing中,不过能说说你case的思路吗?
回复

使用道具 举报

 楼主| 发表于 2003-10-24 13:12:57 | 显示全部楼层
罗马数字的表示方法:
         i       v      x      l      c       d      m
             1      5     10    50   100   500    1000

因为在不同的degree中区分方法是一样的,所以只要确定一个degree,其他就只是换

一下符号了

设阿拉伯数字A为个位数
                A=1,2,3==>i,ii,iii
                        A=4,9==>iv,ix
                        A=5==>v
                        A=6,7,8==>vi,vii,viii

这就是我划分的几种情况,应该有更好的方法吧,没有继续想了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-13 04:09 , Processed in 0.066746 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表