Project Euler 89:Roman numerals 罗马数字

本文探讨了罗马数字的有效写法,通过特定规则将一千个罗马数字转换为其最短形式,并计算节省的字符数量。

Roman numerals

For a number written in Roman numerals to be considered valid there are basic rules which must be followed. Even though the rules allow some numbers to be expressed in more than one way there is always a “best” way of writing a particular number.

For example, it would appear that there are at least six ways of writing the number sixteen:

IIIIIIIIIIIIIIII
VIIIIIIIIIII
VVIIIIII
XIIIIII
VVVI
XVI

However, according to the rules only XIIIIII and XVI are valid, and the last example is considered to be the most efficient, as it uses the least number of numerals.

The 11K text file, roman.txt (right click and ‘Save Link/Target As…’), contains one thousand numbers written in valid, but not necessarily minimal, Roman numerals; see About… Roman Numerals for the definitive rules for this problem.

Find the number of characters saved by writing each of these in their minimal form.

Note: You can assume that all the Roman numerals in the file contain no more than four consecutive identical units.


罗马数字

要正确地用罗马数字表达一个数,必须遵循一些基本规则。尽管符合规则的写法有时会多于一种,但对每个数来说总是存在一种“最好的”写法。

例如,数16就至少有六种写法:

IIIIIIIIIIIIIIII
VIIIIIIIIIII
VVIIIIII
XIIIIII
VVVI
XVI

然而,根据规则,只有XIIIIII和XVI是合理的写法,而后一种因为使用了最少的数字而被认为是最有效的写法。

在这个11K的文本文件roman.txt (右击并选择“目标另存为……”)中包含了一千个合理的罗马数字写法,但并不都是最有效的写法;有关罗马数字的明确规则,可以参考关于罗马数字

求出将这些数都写成最有效的写法所节省的字符数。

注意:你可以假定文件中的所有罗马数字写法都不包含连续超过四个相同字符。

解题

 规则:

VIIII-> IX

IIII -> IV

LXXXX -> XC

XXXX -> XL

DCCCC-> CM

 

CCCC -> CD

上面替代的规则表示不理解

JAVA

package Level3;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;

public class PE089{
    static void run() throws IOException{
        ArrayList<String> roman = getRoman();
        int size = roman.size();
        int res = 0;
        for(int i =0;i<size ;i++){
            String str = roman.get(i);
            res += str.length();
            str = str.replace("IIII", "IV");
            str = str.replace("XXXX", "XL");
            str = str.replace("CCCC", "CD");
            str = str.replace("VIV", "IX");
            str = str.replace("LXL", "XC");
            str = str.replace("DCD", "CM");
            res -= str.length();
        }
        System.out.println(res);
    }
//    743
//    running time=0s22ms
    static ArrayList<String> getRoman() throws IOException{
        ArrayList<String> roman = new ArrayList<String>();
        String filename = "src/Level3/p089_roman.txt";
        BufferedReader data = new BufferedReader(new FileReader(filename));
        String line ="";
        while((line = data.readLine())!= null){
            roman.add(line);
//            System.out.println(line);
        }
        return roman;
    }
    public static void main(String[] args) throws IOException{
        long t0 = System.currentTimeMillis();
        run();
        long t1 = System.currentTimeMillis();
        long t = t1 - t0;
        System.out.println("running time="+t/1000+"s"+t%1000+"ms");

    }
}

 

Python

# coding=gbk

import time as time 
import re 
def run():
    filename = 'E:/java/projecteuler/src/Level3/p089_roman.txt'
    file = open(filename)
    ans = 0
    for line in file:
        a = len(line)
        line = re.sub('IIII','IV',line)
        line = re.sub('XXXX','XL',line)
        line = re.sub('CCCC','CD',line)
        line = re.sub('VIV','IX',line)
        line = re.sub('LXL','XC',line)
        line = re.sub('DCD','CM',line)
        b = len(line)
        ans = ans + a -b 
    print ans 
# 743
# running time= 0.0169999599457 s
t0 = time.time()
run() 
t1 = time.time()
print "running time=",(t1-t0),"s"
  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值