zoukankan      html  css  js  c++  java
  • PAT 甲级测试题目 -- 1010 Radix

    题目链接

    题目描述

    给你两个数以及其中一个数的基数(进制数),找出另一个数的基数,找不到就输出 Impassible

    分析

    思路不是很难,基本可以用进制转换加循环判断做,但是有坑。。。
    坑1:上界不是36.。。。上界是确定的那个数的十进制加 1 。
    坑2:暴力循环会导致时间超限,用二分法解决
    坑3:二分过程中会有数据溢出,得到的负数处理方式和找到较大数处理方式一样,因为溢出的数和题目条件不符,所以可以舍弃。

    实现

    #include<iostream>
    #include<string.h>
    #include<cmath>
    using namespace std;
    
    // 用于判断进制数是否合理,顺便记录下未提供进制数据的进制数,用于优化查找基数次数。
    
    // 任意进制转换为 10 进制
    long long TransSystemToDec(char* number, double radix) {
    	double times = strlen(number) - 1;
    
    	long long out = 0;
    	for (int i = 0; i < strlen(number); i++) {
    		if (number[i] <= '9')
    			out += ((long long)(number[i] - '0')) * pow(radix, times);
    		if (number[i] >= 'a')
    			out += ((long long)(number[i] - 'a' + 10))*pow(radix, times);
    		times--;
    	}
    	return out;
    }
    
    // 查找字符串中ASCII码最大的字符,用于做二分查找下界
    int FindMax(char* N) {
    	int maxChar = '0';
    	for (int i = 0; i < strlen(N); i++) {
    		if (maxChar < N[i])
    			maxChar = N[i];
    	}
    
    	if (maxChar <= '9')
    		maxChar = maxChar - '0';
    	if (maxChar >= 'a')
    		maxChar = maxChar - 'a' + 10;
    	return maxChar;
    
    }
    
    int main() {
    	int maxChar = '0';
    	char N1[11], N2[11];
    	long long n1, n2, left, right, middle;
    	int radix;
    	int tag;
    
    	cin >> N1 >> N2 >> tag >> radix;
    
    	if (tag == 1) {
    		// 将确定的数转换成10进制整数
    		n1 = TransSystemToDec(N1, radix);
    		// 获得不确定数字符串中ASCII码最大的字符,作为二分查找下界
    		maxChar = FindMax(N2);
    		// 初始化二分查找需要的变量
    		left = maxChar + 1;
    		right = n1 + 1; // 上界为确定数的十进制 +1,原因是比(确定数的十进制 + 1)再大的进制数,它对应的(确定数的十进制 +1)这个值在该进制下的表示都不会变化
    		middle = (left + right) / 2;
    
    		while (right >= left) {
    			if (n1 == TransSystemToDec(N2, middle)) {
    				cout << middle;
    				return 0;
    			}
    			// 这里 || 运算符后面的判断用于过滤比 long long 数据类型还大的数据,这样的数据题目中是不会使其符合题意的
    			if (n1 < TransSystemToDec(N2, middle) || (TransSystemToDec(N2, middle) < 0)) {
    				right = middle - 1;
    				middle = (left + right) / 2;
    			}
    			else {
    				left = middle + 1;
    				middle = (left + right) / 2;
    			}
    
    		}
    		cout << "Impossible";
    	}
    	if (tag == 2) {
    		n2 = TransSystemToDec(N2, radix);
    		maxChar = FindMax(N1);
    		left = maxChar + 1;
    		right = n2 + 1;
    		middle = (left + right) / 2;
    
    
    		while (right >= left) {
    			if (n2 == TransSystemToDec(N1, middle)) {
    				cout << middle;
    				return 0;
    
    			}
    			if (n2 < TransSystemToDec(N1, middle) || TransSystemToDec(N1, middle) < 0) {
    				right = middle - 1;
    				middle = (left + right) / 2;
    			}
    			else {
    				left = middle + 1;
    				middle = (left + right) / 2;
    			}
    
    		}
    		cout << "Impossible";
    
    	}
    	return 0;
    }
    

    希望能帮到大家!

  • 相关阅读:
    Linux Apache Mysql PHP楷模设置配备摆设1
    谋划phpMyAdmin2.6以上版本数据乱码题目
    MYSQL到ORACLE法式迁徙的注意变乱
    关于MySQL中的mysqldump饬令的应用
    MySQL 5.0新特性教程 存储进程:第一讲
    Mysql 数据库的导入与导出
    Linux Apache Mysql PHP典范设置装备安排2
    MYSQL数据库初学者运用指南2
    图解MySQL数据库的铺排和操作3
    MySQL完成表中掏出随机数据
  • 原文地址:https://www.cnblogs.com/Breathmint/p/10290244.html
Copyright © 2011-2022 走看看