《C++编程这样学》第十二章:进制问题- 加油站题解

1. 二进制数分类

题目链接:http://csp.magu.ltd/problem/J1255

【问题描述】

将一个十进制正整数化为二进制数,在转换后的二进制数中,将数字1的个数多于数字0的个数的二进制数称为A类数,否则就称其为B类数。
例如:

  • ( 13 ) 10 = ( 1101 ) 2 (13)_{10} = (1101)_2 (13)10=(1101)2,其中1的个数为3,0的个数为1,称此数为A类数;

  • ( 10 ) 10 = ( 1010 ) 2 (10)_{10} = (1010)_2 (10)10=(1010)2,其中1的个数为2,0的个数也为2,称此数为B类数;

  • ( 24 ) 10 = ( 11000 ) 2 (24)_{10} = (11000)_2 (24)10=(11000)2,其中1的个数为2,0的个数为3,称此数为B类数;

编写程序,输入n个十进制正整数,输出这n个整数的类别。

【题解代码】
#include <iostream>
using namespace std;
int a[40];
int main()
{
	int n;
	cin >> n;
	while (n --)
	{
		int x;
		cin >> x;
		int cnt1 = 0, cnt0 = 0;
		while (x)
		{
			if (x % 2 == 1) cnt1 ++;
			else cnt0 ++;
			x /= 2;
		}
		if (cnt1 > cnt0) cout << 'A';
		else cout << 'B';
	}
	return 0;
}

2. 进制合法性

题目链接:http://csp.magu.ltd/problem/J1257

【问题描述】

编写程序,输入T组数据,每组数据由正整数n和字符串s组成(s由数字和大写字母组成),判断s是否为合法的n进制数对应的字符串,其中, 2 ≤ n ≤ 36 2≤n≤36 2n36,字符串中“0” ~ “9”分别表示0 ~ 9,“A” ~ “Z”分别表示10 ~ 35。

【题解代码】
#include <iostream>
#include <cstring>
using namespace std;

char s[110];

void solve()
{
	int n;
	cin >> n >> s;
	char maxx = 0;
	for (int i = 0; i < strlen(s); i ++) {
		if (s[i] > maxx) maxx = s[i];
	}
	int t = 0;
	if (maxx >= '0' && maxx <= '9')
	{
		t = maxx - '0';
	}
	else t = maxx - 'A' + 10;
	if (t >= n) cout << "No" << endl;
	else cout << "Yes" << endl;
}

int main()
{
	int T;
	cin >> T;
	while (T --)
	{
		solve();
	}
	return 0;
}

3. 确定进制

题目链接:http://csp.magu.ltd/problem/J1255

【问题描述】

6 × 9 = 42 6 \times 9=42 \quad 6×9=42 对于十进制来说是错误的,但是对于13进制数来说是正确的。即 6 ( 13 ) × 9 ( 13 ) = 4 2 ( 13 ) 6_{(13)} \times 9_{(13)}=42_{(13)} 6(13)×9(13)=42(13), 而 4 2 ( 13 ) = 4 ∗ 1 3 1 + 2 ∗ 1 3 0 = 5 4 ( 10 ) 42_{(13)}= 4*13^1+2*13^0=54_{(10)} 42(13=4131+2130=54(10)

编写程序,输入三个正整数 p p p q q q r r r,然后确定一个进制 B B B ( 2 ⩽ B ⩽ 16 ) (2 \leqslant B \leqslant 16) 2B16使得 p ∗ q = r p*q=r pq=r。 如果 B B B 有很多选择,则输出最小的一个。

例如: p = 11 , q = 11 , r = 121 p=11,q=11,r=121 p=11q=11r=121
则有 11 ( 3 ) ∗ 11 ( 3 ) = 121 ( 3 ) 11(3)*11(3)=121(3) 11(311(3=121(3

因为 11 ( 3 ) = 1 ∗ 3 1 + 1 ∗ 3 0 = 4 ( 10 ) 11(3)= 1*3^1+1*3^0= 4_{(10)} 11(3=131+130=4(10) 12 1 ( 3 ) = 1 ∗ 3 2 + 2 ∗ 3 1 + 1 ∗ 3 0 = 1 6 ( 10 ) 121_{(3)}= 1*3^2+2*3^1+ 1*3^0= 16_{(10)} 121(3)=132+231+130=16(10)

这时 4 ( 10 ) ∗ 4 ( 10 ) = 1 6 ( 10 ) 4_{(10)}*4_{(10)}= 16_{(10)} 4(10)4(10)=16(10)

对于进制 10 10 10,同样有 1 1 ( 10 ) ∗ 1 1 ( 10 ) = 12 1 ( 10 ) 11_{(10)}*11_{(10)}= 121_{(10)} 11(10)11(10=121(10)

这种情况下,应该输出3。如果没有合适的进制,则输出0。

【题解代码】
#include <iostream>
using namespace std;

// 将base进制下的n,转为10进制的数。若无法转换,返回-1 
int convert(int n, int base)
{
	int ans = 0, p = 1;
	while (n)
	{
		int t = n % 10;
		if (t >= base) return -1;
		ans += t * p;
		p *= base;
		n /= 10;
	}
	return ans;
}

int main()
{
	int p, q, r;
	cin >> p >> q >> r;
	for (int i = 2; i <= 16; i ++)
	{
		if (convert(p, i) == -1 || convert(q,i) == -1 || convert(r,i) == -1) continue;
		if (convert(p, i) * convert(q, i) == convert(r, i))
		{
			cout << i;
			return 0; // 结束程序
		}	
	}	
	cout << 0;
	return 0;
}
  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值