CCF模拟题 37. 计算校验码

tech2022-08-24  106

【问题描述】

传送一个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的倍数 这题主要是字母a-f对应转换到10-15考察对ASCII码的记忆 当然了,这个可以不用记,临时算一下也可以

#include<iostream> #include<cmath> using namespace std; // char a='a'; // int b=a-'0'; // int c=b-10; // int d=a-'0'-c; // cout<<b<<" "<<c<<" "<<d; //实验用,a对应得到10要经过的计算 因为记不清ASCII码了。。。 //a-'0'-39即可 int main(){ int n;cin>>n; int x;string y; for(int i=0;i<n;i++){ cin>>x>>y; int l=y.length(),t=0; for(int j=0;j<l;j++){ if(y[j]>='0'&&y[j]<='9') t+=y[j]-'0'; else t+=y[j]-'0'-39;//把字母也变成数字加起来 } int yu=t%(x-1); if(yu!=0) yu=x-yu-1; //这一步是“加上校验码能被x-1整除”反向求校验码 if(yu<10){ cout<<yu<<endl; } else{ char a=yu+'0'+39; cout<<a<<endl; } } }
最新回复(0)