PAT真题(C语言)——1010:Radix

这是一篇关于PAT考试中的一道C语言编程题目的解析,重点在于寻找一个数字在不同进制下等于指定数值的最小进制。题目陷阱包括进制范围未明确限制和数字大小超出int范围。解决方案采用二分查找法以降低时间复杂度,特别处理了一位数的特殊情况,并讨论了初始化边界值的选择对结果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
在连做了几道简单题以后,突然被这么一道难住,心态还是有点崩的,尤其还是怎么调试都调试不出来,终于,收集了各方资料,不断修改算法,总算拿到了AC,喜大普奔~
现在说题目,题目要求找另一个数是否存在在某一个进制的情况下等于指定的数,这道题的陷阱可以总结如下:

  1. 进制的范围:题目只说了单个数的范围不超过35,但并没有说进制不能超过35;
  2. 数的大小:单纯的int是不足以拿到这道题的AC的,但好在使用long long int足够了,这里不光是存的数字要用long long int,同时进制也得用long long int。
  3. 由于使用了long long,进制如果是使用遍历,就会造成极高的时间复杂度,所以基本都采用了二分查找法,最后的结果也表明,这种方法在时间上表现也不错。
  4. 要求是求出满足条件的最小进制。刚开始做的时候脑子没怎么用,就觉得大不了把所有情况遍历一遍,找出最小的就行,做法就是当遇见正好合适的进制的时候将二分查找法的右值放中间,知道遍历完所有情况。这明显很傻,因为后来突然想到,似乎只有某个数为一位的时候才会有多个进制表示的是同一个数的情况,因此将其单独判断就行。
  5. 最后一个遇到的问题,是high的初始值问题,当取太大,就会有几个测试点过不去,稍微变一点,又会有不同的通过情况,还挺迷的,最后选定的这个初始值能够让所有测试点通过。

代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define int64 long long int

int64 c2i(char c) {
	int64 temp = (int64)(c - '0');
	if (temp>9) {
		temp -= 39;
	}
	return temp;
}

int64 findMinbase(char n[11]){
    int64 res = 1;
    for(int i=0;i<11;i++){
        if(c2i(n[i]) > res)
            res = c2i(n[i]);
        if(n[i] == '\0')
            break;
    }
    return res+1;
}


int64 switchRadix(char n[11], int64 r) {
	int i;
	int64 result = 0;
	int64 time = 1;
    for(i = 0; i<11; i++){
        if(n[i] == '\0')
            break;
    }
	for (i -= 1; i >= 0; i--) {
		result += c2i(n[i])*time;
		time *= r;
	}
	return result;
}

int main(void) {
	char n[2][11];
	int choose;
	int another;
	int64 radix;
	int64 ans;
	int64 que;
	int64 low, high;

	scanf("%s %s %d %lld", n[0], n[1], &choose, &radix);
	another = choose % 2;
	que = switchRadix(n[choose - 1], radix);

	low = findMinbase(n[another]);
	high = 922337203685477580;

	if (strlen(n[another]) == 1) {
		if (c2i(n[another][0]) == que)
			printf("%lld", low);
		else
			printf("Impossible");
		return 0;
	}

	while (low <= high) {
		int64 mid = (high - low) / 2 + low;
		ans = switchRadix(n[another], mid);
		if (ans > que || ans<0)
			high = mid - 1;

		else if (ans < que)
			low = mid + 1;

		else if (ans == que) {
			printf("%lld", mid);
			return 0;
		}

	}
	printf("Impossible");
	return 0;
}

最后需要鞭策自己的是,连个二分查找都还写不利索,还得继续修炼,嗯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值