码迷,mamicode.com
首页 > 编程语言 > 详细

算法-确定进制

时间:2015-06-10 22:25:57      阅读:340      评论:0      收藏:0      [点我收藏+]

标签:

算法-确定进制

题目

描述

6*9 = 42 对于十进制来说是错误的,但是对于13进制来说是正确的。即, 6(13) * 9(13) = 42(13), 而 42(13) = 4 * 131 + 2 * 130 = 54(10)。 你的任务是写一段程序读入三个整数p、q和 r,然后确定一个进制 B(2<=B<=16) 使得 p * q = r. 如果 B有很多选择, 输出最小的一个。例如: p = 11, q = 11, r = 121. 则有 11(3) * 11(3) = 121(3) 因为 11(3) = 1 * 31 + 1 * 30 = 4(10) 和 121(3) = 1 * 32 + 2 * 31 + 1 * 30 = 16(10)。 对于进制 10,有 11(10) * 11(10) = 121(10)。这种情况下,应该输出 3。如果没有合适的进制,则输出 0。

输入

输入有 T组测试样例。 T在第一行给出。每一组测试样例占一行,包含三个整数p、q、r。 p、q、r的所有位都是数字,并且1 <= p、q、r <= 1,000,000。

输出

对于每个测试样例输出一行。该行包含一个整数:即使得p * q = r成立的最小的B。如果没有合适的B,则输出

样例输入

3
6 9 42
11 11 121
2 2 2

样例输出

13
3
0

来源

http://bailian.openjudge.cn/practice/2972

解题思路

关键点

  1. p、q、r的所有位都是数字,且范围为[1,1000000];

  2. 进制范围为2~16

思路

将p,q,r转换成十进制判断p*q是否等于r

伪代码如下:
1.遍历 i -> [2,16]
2.将p,q,r当成是i进制的数转换成10进制,设转换后的数为p(i),q(i),r(i)
3.判断p(i)*q(i) ?= r(i),相等时返回i;

可以看出来,整个题目的难点在于将转入的数字转换成10进制,这个过程解决了,基本上就成功了90%。首先,复习一下进行的转换。

进制转换

有一个公式:二进制数、八进制数、十六进制数的各位数字分别乖以各自的基数的(N-1)次方,其和相加之和便是相应的十进制数。个位,N=1;十位,N=2...举例:
110B=1x2的2次方+1x2的1次方+0x2的0次方=0+4+2+0=6D
110Q=1x8的2次方+1x8的1次方+0x8的0次方=64+8+0=72D
110H=1x16的2次方+1x16的1次方+0x16的0次方=256+16+0=272D

转换函数

根据公式可以确定,输入为需要转换的数n,基数b,转出为对应的十进制整数。另外,如果输入number中的某位上的数字大于等于base,那么这个number不可能是base进制的数。因此,需要返回一个结果来标识这种状态,这里返回-1来表示

另外,输出最大为1000000H = 1*16^6 = 2^24 < 2^31-1,因此返回用int即可,函数声明如下。

int tranToDecimal(unsigned number,unsigned base);

具体实现如下:

/*
 * b进制转成10进制
 * A(n)A(n-1)A(n-2)...A(1)A(0) = A(0)*b^0 + A(1)*b^1 + ... + A(n)*b^(n)
 */
int tranToDecimal(unsigned number,unsigned base){
    int sum = 0;
    int k = 1;
    while (number) {
        //求子项值
        int remainder = number % 10;
        //不能大于进制
        if (remainder >= base) {
            return -1;
        }
        remainder *= k;
        sum += remainder;
        
        //处理子项值需要的参数
        number /= 10;
        k *= base;
    }
    
    return sum;
}

最终实现

有了上述函数后,剩下的就容易处理了,最终实现的代码如下:

int main(int argc, const char * argv[]) {
    // insert code here...
    int n;
    scanf("%d",&n);
    
    for (int i = 0; i < n; i++) {
        unsigned p;
        unsigned q;
        unsigned r;
        bool hasBase = false;
        
        scanf("%d %d %d",&p,&q,&r);
        for (int i = 2; i <= 16; i++) {
            unsigned p10 = tranToDecimal(p, i);
            unsigned q10 = tranToDecimal(q, i);
            unsigned r10 = tranToDecimal(r, i);
            
            if (p10 != -1 && q10 != -1 && r10 != -1 && p10 * q10 == r10){
                hasBase = true;
                printf("%d\n",i);
                break;
            };
        }
        
        if (!hasBase) {
            printf("0\n");
        }
    }
    
    return 0;
}

算法-确定进制

标签:

原文地址:http://www.cnblogs.com/limaofuyuanzhang/p/4567257.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!