甲級-1010 Radix (25 分)

題目:

Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is yes, if 6 is a decimal number and 110 is a binary number.

Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of the other is given.

Input Specification:

Each input file contains one test case. Each case occupies a line which contains 4 positive integers:

N1 N2 tag radix

Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set { 0-9, a-z } where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35. The last number radix is the radix of N1 if tag is 1, or of N2 if tag is 2.

Output Specification:

For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print Impossible. If the solution is not unique, output the smallest possible radix.

Sample Input 1:

6 110 1 10

Sample Output 1:

2

Sample Input 2:

1 ab 1 2

Sample Output 2:

Impossible

解題思路:

題目本身并不是很難,假設給出了N1的進制,可以先將N1轉化為十進制遣耍,然后從(radix=2)開始以某種方式試探N2的進制,最后使得N2在轉換為十進制后與N1相等即可崖蜜。只是這上面的坑有點多。

坑點:

1.需要注意烙肺,測試用例中給出的radix不一定小于等于36纳猪,而且本題中出現(xiàn)的數(shù)據(jù)都遠超過int能保存的范圍,到目前為止個人覺得最好的辦法還是自己構建一個類來保存數(shù)據(jù)桃笙。筆者是使用deque<int>來保存數(shù)據(jù)的氏堤,但畢竟不是自己單獨定義的類,導致編碼看起來很混亂搏明。
之后查看其他人的解題思路發(fā)現(xiàn)用long long就可以……所以大概是我多慮了)
2.除了數(shù)據(jù)過大之外鼠锈,在查找目標radix的過程中需要運用適當?shù)姆椒ǎ蝗粫瑫r星著」喊剩看網絡上其他人的方法多為使用二分查找,在這里我感覺再對deque<int>定義除法運算太耗時了虚循,便取巧定義了一個變量做“步長”——
第一次以1111111111為步長搜索同欠,
第二次以111111111為步長搜索,
……
最后一次以1為步長搜索横缔,
在步長為1時搜索必然能命中結果铺遂,若不命中,則說明不存在茎刚,打印Impossible襟锐。使用此方法,最后也不會超時膛锭。
3.需要考慮到的特殊情況:進制數(shù)應大于原數(shù)中的每一位粮坞;當答案不唯一時蚊荣,輸出最小的進制數(shù)。即——
當test case為10 50 1 10時應輸出Impossible莫杈,而非2互例;
當test case為3 3 1 10時應輸出4,而不是其他數(shù)字姓迅。

代碼:

編譯器:C++(g++)

#include <iostream>
#include <string>
#include <deque>
using namespace std;

//數(shù)字轉換為deque<int>的形式
deque<int> atodeq(long long n)
{
    deque<int> ret;
    while(n!=0)
    {
        ret.push_front(n%10);
        n/=10;
    }
    return ret;
}
//兩個deque<int>形式的數(shù)字相加
deque<int> sum(deque<int> s1,deque<int> s2)
{
    if(s1.size()<s2.size())
    {
        swap(s1,s2);
    }
    int jinwei=0;
    deque<int> ret;
    while(!s2.empty())
    {
        ret.push_front((s1.back()+s2.back()+jinwei)%10);
        jinwei=(s1.back()+s2.back()+jinwei)/10;
        s1.pop_back();
        s2.pop_back();
    }
    while(!s1.empty())
    {
        ret.push_front((s1.back()+jinwei)%10);
        jinwei=(s1.back()+jinwei)/10;
        s1.pop_back();
    }
    if(jinwei!=0)
    {
        ret.push_front(jinwei);
    }
    return ret;
}
//兩個deque<int>形式的數(shù)字相乘
deque<int> times(deque<int> s1,deque<int> s2)
{
    int i=0;
    deque<int> ret(1,0);
    while(!s2.empty())
    {
        deque<int> tmp=s1;
        int jinwei=0;
        for(int j=tmp.size()-1;j>=0;--j)
        {
            int t=tmp[j];
            tmp[j]=(t*s2.back()+jinwei)%10;
            jinwei=(t*s2.back()+jinwei)/10;
        }
        if(jinwei!=0)
        {
            tmp.push_front(jinwei);
        }
        for(int j=0;j!=i;++j)
        {
            tmp.push_back(0);
        }
        ++i;
        ret=sum(ret,tmp);
        s2.pop_back();
    }
    return ret;
}
//將str形式的radix進制的數(shù)字轉換為10進制的deque<int>的形式
deque<int> toDecimal(const string &str,long long radix)
{
    deque<int> ret(1,0);
    string num=str;
    for(deque<int> i(1,1);!num.empty();i=times(i,atodeq(radix)))
    {
        int t;
        if(num.back()>='0'&&num.back()<='9')
        {
            t=num.back()-'0';
        }
        else
        {
            t=num.back()-'a'+10;
        }
        ret=sum(ret,times(atodeq(t),i));
        num.pop_back();
    }
    return ret;
}
deque<int> toDecimal(const string &str,deque<int> radix)
{
    deque<int> ret(1,0);
    string num=str;
    for(deque<int> i(1,1);!num.empty();i=times(i,radix))
    {
        int t;
        if(num.back()>='0'&&num.back()<='9')
        {
            t=num.back()-'0';
        }
        else
        {
            t=num.back()-'a'+10;
        }
        ret=sum(ret,times(atodeq(t),i));
        num.pop_back();
    }
    return ret;
}

int main()
{
    string n1,n2;
    int tag;
    long long radix;
    cin>>n1>>n2>>tag>>radix;
    //特殊情況:兩者都是個位數(shù)
    if(1==n1.size()&&1==n2.size())
    {
        if(n1==n2)
        {
            if(n1.back()>='0'&&n1.back()<='9')
            {
                cout<<(n1.back()-'0'+1)<<endl;
            }
            else
            {
                cout<<(n1.back()-'a'+11)<<endl;
            }
        }
        else
        {
            cout<<"Impossible"<<endl;
        }
        return 0;
    }
    //特殊情況:兩者相等(但不是個位數(shù))
    if(n1==n2)
    {
        cout<<radix<<endl;
        return 0;
    }
    deque<int> num;
    if(2==tag)
    {
        swap(n1,n2);
    }
    num=toDecimal(n1,radix);
    //考慮最小進制數(shù)應大于每一位數(shù)的情況
    int minRet=2;
    for(auto it=n2.cbegin();it!=n2.cend();++it)
    {
        if(*it>='0'&&*it<='9')
        {
            minRet=((*it-'0'+1)>minRet?(*it-'0'+1):minRet);
        }
        else
        {
            minRet=((*it-'a'+11)>minRet?(*it-'a'+11):minRet);
        }
    }
    if(n1.size()<n2.size()||(n1.size()==n2.size()&&n1<n2))
    {
        //進制在2~radix
        long long min=minRet,max=radix-1,ret=(min+max)/2;
        while(1)
        {
            if(min>max)
            {
                //min>max說明沒有合適的進制
                cout<<"Impossible"<<endl;
                return 0;
            }
            auto result=toDecimal(n2,ret);
            if(result.size()<num.size()||(result.size()==num.size()&&result<num))
            {
                //小于則向后半區(qū)查找
                min=ret+1;
                ret=(min+max)/2;
            }
            else if(result.size()>num.size()||(result.size()==num.size()&&result>num))
            {
                //大于則向前半區(qū)查找
                max=ret-1;
                ret=(min+max)/2;
            }
            else
            {
                //等于則輸出
                cout<<ret<<endl;
                return 0;
            }
        }
    }
    else
    {
        //進制>radix
        deque<int> ret=atodeq((radix>minRet?radix:minRet)),pre=ret;
        //考慮n2為個位數(shù)的情況
        if(1==n2.size())
        {
            if(toDecimal(n2,ret)!=num)
            {
                cout<<"Impossible"<<endl;
                return 0;
            }
        }
        int increase=10;    //步長
        while(1)
        {
            auto result=toDecimal(n2,ret);
            if(result==num)
            {
                for(auto it=ret.cbegin();it!=ret.cend();++it)
                {
                    cout<<*it;
                }
                cout<<endl;
                return 0;
            }
            else if(result.size()>num.size()||(result.size()==num.size()&&result>num))
            {
                //步長為1的時候必然會命中敲霍,否則就是Impossible
                if(increase!=1)
                {
                    --increase;
                    ret=pre;
                }
                else
                {
                    cout<<"Impossible"<<endl;
                    return 0;
                }
            }
            pre=ret;
            ret=sum(ret,deque<int>(increase,1));
        }
    }
    return 0;
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丁存,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柴我,老刑警劉巖解寝,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異艘儒,居然都是意外死亡聋伦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門界睁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來觉增,“玉大人,你說我怎么就攤上這事翻斟∮饨福” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵访惜,是天一觀的道長嘹履。 經常有香客問我,道長债热,這世上最難降的妖魔是什么砾嫉? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮窒篱,結果婚禮上焕刮,老公的妹妹穿的比我還像新娘。我一直安慰自己墙杯,他們只是感情好配并,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霍转,像睡著了一般荐绝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上避消,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天低滩,我揣著相機與錄音召夹,去河邊找鬼。 笑死恕沫,一個胖子當著我的面吹牛监憎,可吹牛的內容都是我干的。 我是一名探鬼主播婶溯,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼鲸阔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迄委?” 一聲冷哼從身側響起褐筛,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叙身,沒想到半個月后渔扎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡信轿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年晃痴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片财忽。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡倘核,死狀恐怖,靈堂內的尸體忽然破棺而出即彪,到底是詐尸還是另有隱情紧唱,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布祖凫,位于F島的核電站琼蚯,受9級特大地震影響,放射性物質發(fā)生泄漏惠况。R本人自食惡果不足惜遭庶,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稠屠。 院中可真熱鬧峦睡,春花似錦、人聲如沸权埠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攘蔽。三九已至酱塔,卻和暖如春渡蜻,著一層夾襖步出監(jiān)牢的瞬間热某,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工作岖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人五芝。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓痘儡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親枢步。 傳聞我的和親對象是個殘疾皇子沉删,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容