洛谷普及B2141确定进制

题目:确定进制

题号:B2141

难度:普及一

题目分析

大致思路

编写函数转换进制,然后通过for循环遍历进制,找出符合条件的目标进制

起初思路想反了,写的函数是将十进制转化为别的进制,然后计算判断,代码如下

这串代码,不仅思路反了,而且所用的函数 itoa 和 aoti 不是C语言标准库函数,是某些编译器独有的,这就导致压根编译都过不去。

解决方法

//需要费时间写几个函数来转换一下,现在是3月30凌晨,,白天刚考完计算机考试,
//正好明天也没啥事,那就试着沉浸式设计一下这几个函数,然后合并判断输出。

//int Change_Zhi(int num,int a[100],int n)

参数分别代表 num是需要转换的十进制数  a是转换后的结果承载数组,n代表目标进制(基数)
//基本思路构建:我打算采用除基取余法,这样的话得到的结果是逆序的,
//但是后面是需要将数组中的各个数合成转化为一个十进制整合数的,
//所以在下个步骤转化时设计数组前位乘指数小位,这样就不用将数组再逆序了,方便多了

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

int Change_Zhi(int num,int a[100],int n)
 
{
	int wei = 0;
	while(num>0) 
	{	a[wei++] = num % n;
		num /= n; 	}
	return wei-1;//存储了几位-1 
}
int HeBing(int a[100],int wei)
{
	int zheng = 0;
	for(int i=0;i<=wei;i++)
		zheng += a[i] * pow(10,i);
		return zheng;
}

int main()
{
int p,q,r,P[17][100],Q[17][100],R[17][100];
int pw,qw,rw,pp,qq,rr,b=0,i;
scanf("%d %d %d",&p,&q,&r);
for(i=2;i<=16;i++) //切换进制的主循环 
 {
pw = Change_Zhi(p,P[i],i);
qw = Change_Zhi(q,Q[i],i);
rw = Change_Zhi(r,R[i],i);
	pp = HeBing(P[i],pw);
	qq = HeBing(Q[i],qw);
	rr = HeBing(R[i],rw);
 	if(pp * qq == rr)
	 {printf("%d",i);
	 	b=1;
	 break;}
 }
if(!b)
printf("0");
	return 0;
}

这串代码其实在思路上还是与上个代码类似,还是反的,当时我没意识到,而这串代码的目的,是用编写的函数来代替本来编译不了的函数,

函数一:int Change_Zhi(int num,int a[100],int n) return wei;

通过将十进制的num转化为n进制数并且储存在数组a中,返回的是数组a中存储的位数。

函数二:int HeBing(int a[100],int wei) return zheng;

这段是将数组a中的各个位数合并成一个整数,并通过函数值返回。

上述这两个代码其实都是倒序的,但是两个代码合作就抵消了这种倒序。

解决问题

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int jc(int x,int n)
{ 
if(n==0)
return 1;
int c = x;
int g = x;
	for(int i=1;i<n;i++)
	g *= c;	
	return g;
}
int Change_zhi(int num,int n)
{
	int zheng = 0,wei=0,i;
	int a[100];
	while(num>0)
	{	a[wei++] = num % 10;	
	num /= 10;
	if(a[wei-1]>n)
		return 0;
		}
	for(i=0;i<wei;i++)
		zheng += a[i] * jc(n,i);
	return zheng;
}

int main()
{
int p,q,r,i,b=0;
scanf("%d %d %d",&p,&q,&r);
for(i=2;i<=16;i++)
if(Change_zhi(p,i)&&Change_zhi(q,i)&&Change_zhi(r,i)&&Change_zhi(p,i)*Change_zhi(q,i)==Change_zhi(r,i))
	{	printf("%d",i);
		b=1;
		break;	}
if(!b)
printf("0");
return 0;
}

最后编写的函数,就解决了原先思路相反的问题,是将别的进制转化为十进制数,

函数 int Change_zhi(int num,int n) return zheng;

在函数中设下保护,防止转换的数之中存在大于进制的数,并且整体放到main中的if中。

总结代码

总体细节上对应题目要求还有些不足,需要使用long long来替换int,以备使用进制较长的情况

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

// 将字符串表示的数字转换为指定进制下的十进制值
long long c(const char *s, int b) {
    long long r = 0;
    int l = 0;
    while (s[l] != '\0') {
        l++;
    }
    for (int i = 0; i < l; i++) {
        int d;
        if (s[i] >= '0' && s[i] <= '9') {
            d = s[i] - '0';
        } else {
            d = s[i] - 'A' + 10;
        }
        if (d >= b) {
            return -1;
        }
        r = r * b + d;
    }
    return r;
}

// 寻找满足 p × q = r 的最小进制
int f(int x, int y, int z) {
    char xs[20], ys[20], zs[20];
    sprintf(xs, "%d", x);
    sprintf(ys, "%d", y);
    sprintf(zs, "%d", z);

    for (int b = 2; b <= 16; b++) {
        long long xd = c(xs, b);
        long long yd = c(ys, b);
        long long zd = c(zs, b);

        if (xd != -1 && yd != -1 && zd != -1 && xd * yd == zd) {
            return b;
        }
    }
    return 0;
}

int main() {
    int x, y, z;
    scanf("%d %d %d", &x, &y, &z);

    int b = f(x, y, z);
    printf("%d\n", b);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LAOLONG-C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值