1. 程式人生 > >leetcode:Integer to Roman 淺談古羅馬OI生活之數字的研究

leetcode:Integer to Roman 淺談古羅馬OI生活之數字的研究

這裡寫圖片描述
世界真的很大
算是一道大模擬
模擬題有些時候直接按照題目的要求來寫會很麻煩,但是稍微轉化思路之後會很簡單
模擬題有時候也是有思維含量的,也是要小心注意才是

description:

T組資料,每組資料給出一個正整數,輸出其在羅馬數字下的表示方法

input:

第一行一個整數T,接下來T行每行一個整數

output:

輸出T行,每行一個字串表示答案

首先什麼是羅馬數字呢?
就是很多時候能看見的 I,II,III,IX之類的很裝逼的東西
簡單介紹一下:

相同的數字連寫、所表示的數等於這些數字相加得到的數、如:Ⅲ=3;
小的數字在大的數字的右邊、所表示的數等於這些數字相加得到的數、 如:Ⅷ=8、Ⅻ=12;
小的數字(限於 I、X 和 C)在大的數字的左邊、所表示的數等於大數減小數得到的數、如:Ⅳ=4、Ⅸ=9;
正常使用時、連寫的數字重複不得超過三次;
在一個數的上面畫一條橫線、表示這個數擴大 1000 倍。
(百度百科)

由於我們輸出的時候沒法加上劃線,所以就輸出小寫就行了

由於題面的限制實在是太多了,當時讀的突然是頭大,心想這一定是一道非常厲害的大模擬
正在我潛心轉研這玩意兒的拼寫規則(太多了)時,忽然靈光一現
什麼樣的人會用這種數字啊?羅馬人啊,他們難道每次寫數字的時候拼寫都這麼麻煩嗎?
不可能,除非羅馬人全是愛因斯坦
那麼只是一個普通的羅馬人,當他知道了,比如說18這個數的時候,肯定有一個方法快速寫出來,就像我們寫阿拉伯數字一樣
考慮我們在得知18這個數的時候,大腦是怎麼得出18這個數字對應的阿拉伯字元的
10進位制拆分。
我們大概是把18拆成10和8再在不同的數位上分別來寫的
這是由於我們採用的是10進位制的結果
羅馬人的數字I,V,X等等怎麼看都和10有關係,他們可能也是差不多的想法?
那我們就考慮只是去拼寫每一位的數字在拼接起來,發現和那些奇奇妙妙的限制正好吻合
而且對於每一個數位,都有1,5,10的結構,如10,50,100,500,1000等
每一位的表示規則完全相同只是字母不一樣
而且間距也是相同的
那麼從最低位開始,判斷當前位是1~9的哪一個,然後用不同的寫法
有一個叫做string的東西可以通過“+”直接拼接,很好用

完整程式碼:

#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;

int T=0;
string mp[]={"I","V","X","L","C","D","M","v","x","l","c","d","m"};

void sov(int tmp)
{
    int i=0;
    string ans="";
    while(tmp)
    {
        int x=tmp%10;
        if(x==1) ans=mp[i]+ans;
        else
if(x==2) ans=mp[i]+mp[i]+ans; else if(x==3) ans=mp[i]+mp[i]+mp[i]+ans; else if(x==4) ans=mp[i]+mp[i+1]+ans; else if(x==5) ans=mp[i+1]+ans; else if(x==6) ans=mp[i+1]+mp[i]+ans; else if(x==7) ans=mp[i+1]+mp[i]+mp[i]+ans; else if(x==8) ans=mp[i+1]+mp[i]+mp[i]+mp[i]+ans; else if(x==9) ans=mp[i]+mp[i+2]+ans; i+=2,tmp/=10; } cout << ans << endl ; } int main() { scanf("%d",&T); while(T--) { int x; scanf("%d",&x); sov(x); } return 0; }

嗯,就是這樣