21. 校验码

该程序实现了一个功能,根据给定的进制B和B进制的正整数N,计算并添加校验码,使得新数值能被B-1整除。程序首先将输入的B进制数转换为十进制,然后计算各位数字之和,通过遍历找到一个数使总和能被B-1整除,这个数即为校验码。最后,将校验码转换回原进制形式输出。示例中给出了四组测试数据,分别验证了不同进制下校验码的正确性。
摘要由CSDN通过智能技术生成

【问题描述】

传送一个B(B≤16)进制的数值N时,最后加上一个一位(B进制的)校验码,使得N加上校验位后能被B-1整除。比如十进制的数值12310,其校验码就是3,因为十进制数值123310能被9整除。16进制的数7816,其校验码为0,因为16进制的78016是15的倍数。超过十进制后,用字母a表示10,字母b表示11,字母c表示12,字母d表示13,字母e表示14,字母f表示15。

告诉你进制B,以及一个B进制的正整数N,要求你计算正整数N在B进制下的校验码。

【输入形式】

输入第一行正整数t (10 ≤ n ≤ 100),表示有多少组测试数据。

后面有t行,每行两个正整数B,N(2≤ B≤16),中间用一个空格隔开,B是10进制整数,N用B进制形式表示。测试数据保证没有非法的B进制数N(也即N中每一位都是在0到B-1之间,没有前导0)。

40%的测试数据N的位数L 1 ≤ L≤ 10;

30%的测试数据N的位数L 1 ≤ L≤ 102;

20%的测试数据N的位数L 1 ≤ L≤ 103;

10%的测试数据N的位数L 1 ≤ L≤ 104;

【输出形式】

对于每组测试数据,输出一位占一行:正整数N在B进制下的校验码。(如果校验码可以为B-1,也可以为0,输出0)。

【样例输入】

4
10 123
16 78
16 1234321
12 ab

【样例输出】

3
0
e
1

【样例说明】

第一行的4表示有4组测试数据,下面四行,每行一组测试数据。

第一组测试数据 10进制数123 最后添加检验码3,10进制数1233是9(=10-1)的倍数

第二组测试数据 16进制数78 最后添加检验码0,16进制数780是15(=16-1)的倍数

第三组测试数据 16进制数1234321 最后添加检验码e(=14),16进制数1234321e是15(=16-1)的倍数

第四组测试数据 12进制数ab 最后添加检验码1,12进制数ab1是11(12-1)的倍数

【Tips】

B进制的数能被B-1整除,当且仅当各位数字和能被B-1整除。

第一组测试数据 10进制数123 最后添加检验码3,10进制数1233各位数字和是9,是9的倍数

第二组测试数据 16进制数78 最后添加检验码0,16进制数780各位数字和是15,是15的倍数

第三组测试数据 16进制数1234321 最后添加检验码e,16进制数1234321e各位数字和是30,是15的倍数

第四组测试数据 12进制数ab 最后添加检验码1,12进制数ab1各位数字和是22,是11的倍数

注意:查看题干最后的tips,将会变得十分简单 。

#include<bits/stdc++.h>
using namespace std;
int numchange(char);//将输入的字母转换为相应的数字 
char charchange(int sss);//将所得校验码转换为相应的字母 
int main() {
	int t;//测试组数
	cin>>t;
	while(t--) {
		int B;//进制
		string n;//
		cin>>B;
		cin>>n;
		int key=B-1;
		int sum=0;
		int temp;
		char ckey;
		for(int i=0; i<n.size(); i++) {
			if(n[i]>='a'&&n[i]<='f') { //需要进行转换
				temp=numchange(n[i]);
			} else {
				stringstream ss;
				ss<<n[i];
				ss>>temp;
				ss.clear();
			}
			sum+=temp;
		}
		for(int j=0; j<=15; j++) {
			if((sum+j)%key==0) {
				if(j>=0&&j<=9) {
					cout<<j<<endl;
					break;
				} else {
					ckey=charchange(j);
					cout<<ckey<<endl;
					break;
				}
			}
		}
	}
}
int numchange(char ss) {
	int temp1;
	switch(ss) {
		case 'a': {
			temp1=10;
			break;
		}
		case 'b': {
			temp1=11;
			break;
		}
		case 'c': {
			temp1=12;
			break;
		}
		case 'd': {
			temp1=13;
			break;
		}
		case 'e': {
			temp1=14;
			break;
		}
		case 'f': {
			temp1=15;
			break;
		}
	}
	return temp1;
}
char charchange(int sss) {
	char temp2;
	switch(sss) {
		case 10: {
			temp2='a';
			break;
		}
		case 11: {
			temp2='b';
			break;
		}
		case 12: {
			temp2='c';
			break;
		}
		case 13: {
			temp2='d';
			break;
		}
		case 14: {
			temp2='e';
			break;
		}
		case 15: {
			temp2='f';
			break;
		}
	}
	return temp2;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值