zoukankan      html  css  js  c++  java
  • 1010 Radix 二分

    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

    /*
        Name:
        Copyright:
        Author:  流照君
        Date: 2019/8/8 8:43:49
        Description:
    */
    #include <iostream>
    #include<string>
    #include <algorithm>
    #include <vector>
    #define inf 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    string n1,n2,s;
    ll tag,radix,t1,t2,sum=0,flag=0;
    void find(int l,int r)
    {
    	if(l>r)
    	return ;
    	ll sum1=0;
    	ll z=(l+r)/2;
    	for(int i=0;i<=s.size()-1;i++)
        {
        	if(isdigit(s[i]))
        	sum1=sum1*z+(s[i]-'0');
        	else if(isalpha(s[i]))
        	sum1=sum1*z+(s[i]-87);
        	if(sum1>sum)
    		{
    			find(l,z-1);
    			return ;
    		 } 
    	}
    	if(sum1>sum)
    	{
    	find(l,z-1);
    	return ;
    }
    	else if(sum1<sum)
    	{
    	find(z+1,r);
    	return ;
    }
    	else if(sum1==sum)
    	{
    		//cout<<sum1<<endl;
    		cout<<z<<endl;
    		flag=1;
    		return ;
    	}
    }
    int main(int argc, char** argv)
    {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout); 
        cin>>n1>>n2>>tag>>radix;
        if(n1==n2)
        {
        	cout<<radix;
        	return 0;
    	}
    	if(n1==n2&&n1.size()==1&&n1[0]=='1')
    	{
    		cout<<2;
    		return 0;
    	}
        t1=n1.size();
        t2=n2.size();
        if(tag==1)
        {
        	for(int i=0;i<=n1.size()-1;i++)
        	{
        		if(isdigit(n1[i]))
        		sum=sum*radix+(n1[i]-'0');
        		else if(isalpha(n1[i]))
        		sum=sum*radix+(n1[i]-87);
    		}
    		s=n2;
    	}
    	else if(tag==2)
    	{
    		for(int i=0;i<=n2.size()-1;i++)
        	{
        		if(isdigit(n2[i]))
        		sum=sum*radix+(n2[i]-'0');
        		else if(isalpha(n2[i]))
        		sum=sum*radix+(n2[i]-87);
    		}
    		s=n1;
    	}
    	//cout<<s<<sum<<endl;
    	find(1,100000000);
    	if(flag==0)
    	cout<<"Impossible"<<endl;
        return 0;
    }
    

      

    因为单调性所以二分查找(binary search)

    此题没有交代清楚 input 中 radix 的取值范围以及对一位数有多重可能 radix 的情况如何输出,坑比较大。下面是需要注意的点。

    • 1.input 中两个数字可以是 10 位数,虽然没有告诉 radix 的范围,但在9*10^10 10 1 200这个示例中,可以看到结果的 radix 也可以是很大的。从这个角度看,代码中将 radix 和两个数值都设定为 longlong 是合适的选择。
    • 2.在计算另一个数的 radix 时,简单的遍历 [2, 1018]会超时。单调的区间很自然想到使用二分查找。
    • 3.二分查找的上下界确定能减少耗时:下界选数字的所有位上的最大值+1;上界容易想当然的认为就是题中给定了 radix 的数的值。实际上,示例11 b 1 10就是一个反例,原因在于这个假设忽略了一位数的可能性,解决方案是在取给定 radix 的数值和下界中较大的那个数。
    • 4.在二分查找时,不可直接计算出某个 radix 下数的值,因为可能会 longlong 溢出。于是需要用特定的 compare 函数,在累加的过程中判定是否大于另一个数。算是一种剪枝。
    • 5.还有一个条件:当两个数都是 1 时,输出 2.当两个数相等且不为 1 时,输出题中给出的 radix。
  • 相关阅读:
    图片剪纸刀:批量切割图片工具
    Photosynth软件试用(将照片拼接成实景)
    制作一份简单的网络地图(世博地图的配准和切割)
    Discuz论坛地图插件(通过自定义Discuz Code实现)
    Maven Settings.xml 配置模板
    CentOS 7 firewalld 配置详解 (转)
    Silverlight学习笔记八右键菜单控件
    Silverlight学习笔记十三关于SilverLight的打印
    Silverlight学习笔记十二动态加载图片和显示提示(ToolTip)
    Silverlight学习笔记十一动态创建TabContro的TabItem
  • 原文地址:https://www.cnblogs.com/liuzhaojun/p/11324981.html
Copyright © 2011-2022 走看看