【算法总结】%运算符与取余运算
取余套路:
对取得的余数加上除数后,再对该和求除数的模,即可解决符号问题,保证取余结果恒正。(这里b是绝对值,恒大于0)
ans = (r+b)%b
一、数位拆解
数位拆解即把一个给定的数字(如 3241)各个数位上的数字拆开,即拆成 3、 2、4、1。
AC代码(数学方法)
#include<cstdio> int main() { int a, b;//保存两个整数的变量 while (scanf("%d%d", &a, &b) != EOF)//输入两个整数 { int buf1[20], buf2[20], size1 = 0, size2 = 0;//用buf1,buf2分别保存从两个整数中拆解出来的数位数字,其数量由size1,size2表示 while (a != 0)//数位拆解,只要a>0就不断重复拆解过程 { buf1[size1++] = a % 10;//取得个位数字 a /= 10;//数位移动 } while (b != 0)//拆解第二个数字 { buf2[size2++] = b % 10; b /= 10; } int ans = 0; for (int i = 0; i < size1; i++) for (int j = 0; j < size2; j++) ans += buf1[i] * buf2[j]; printf("%d ", ans);//打印答案 } return 0; }
AC代码(字符串方法)
#include<cstdio> int main() { char a[11], b[11]; while (scanf("%s%s", a, b) != EOF) { int ans = 0; for (int i = 0; a[i] != 0; i++) for (int j = 0; b[j] != 0; j++) ans += (a[i] - '0')*(b[j] - '0'); printf("%d ", ans);//打印答案 } return 0; }
二、进制转换
当要求十进制数 x 的 k 进制表示时,我们只需不断的重复对 x 求余(对 k),求商(除以 k),即可由低到高依次得到各个数位上的数。反过来, 要求得由 k 进制表示的数字的十进制值时,我们需要依次计算各个数位上的数字 与该位权重的积(第 n 位则权重为kn-1),然后将它们依次累加即可得到该十进制值。
AC代码
#include<cstdio> int main() { long long a, b;//确保不会溢出 int m; while (scanf("%d", &m) != EOF) { if (m == 0)break;//退出条件 scanf("%lld%lld", &a, &b); a = a + b; int ans[50], size = 0;//用ans保存转换得到的数位数字值,size为其个数 do//依次求得各个数位上的值 { ans[size++] = a % m; a /= m; } while (a != 0);//当a不为0时重复该过程 for (int i = size - 1; i >= 0; i--) printf("%d", ans[i]);//从高位到低位输出 printf(" "); } return 0; }
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int main() { int m; long long a, b, t; while (scanf("%d", &m) != EOF && m != 0) { int s[40]; scanf("%lld%lld", &a, &b); t = a + b; int cnt = 0; do { s[cnt++] = t % m; t /= m; } while (t != 0); for (int i = cnt - 1; i >= 0; i--) { printf("%d", s[i]); } printf(" "); } //system("pause"); return 0; }
AC代码
#include<cstdio> #include<cstring> int main() { int a, b; char str[40]; while (scanf("%d%s%d", &a, str, &b) != EOF) { int tmp = 0, lenth = strlen(str), c = 1;//tmp是我们将要计算的a进制对应的十进制数,lenth为字符串长度,方便从低位到高位遍历数位数字,c为各个数位上的权重,初始化为1,表示最低位数位权重为1,之后每位权重都是前一位的a倍 for (int i = lenth - 1; i >= 0; i--)//从低位到高位遍历每个数位上的数 { int x;//计算该位上的数字 if (str[i] >= '0'&&str[i] <= '9')x = str[i] - '0';//是数字 else if (str[i] >= 'a'&&str[i] <= 'z')x = str[i] - 'a' + 10;//是小写字母,计算其代表的数字 else x = str[i] - 'A' + 10;//是大写字母 tmp += x * c;//累加该位数字与该数位权重的积 c *= a;//计算下一位数位权重 } char ans[40], size = 0;//用ans保存转换到b进制的各个数位数字 do { int x = tmp % b;//计算该位数字 ans[size++] = (x < 10) ? x + '0' : x - 10 + 'A';//将该位数字转换为字符 tmp /= b; } while (tmp); for (int i = size - 1; i >= 0; i--)printf("%c", ans[i]); printf(" "); } return 0; }
#include<cstdio> #include<cstring> using namespace std; int main() { int a, b; char r[50]; while (scanf("%d%s%d", &a, r, &b) != EOF) { int len = strlen(r); long long tmp = 0; for (int i = 0; i < len; i++) { tmp *= a; if (r[i] >= '0'&&r[i] <= '9')tmp += r[i] - '0'; else if (r[i] >= 'a'&&r[i] <= 'f')tmp += r[i] - 'a' + 10; else if (r[i] >= 'A'&&r[i] <= 'F')tmp += r[i] - 'A' + 10; } int size = 0; char ans[50]; while (tmp > 0) { int t = tmp % b; if (t < 10) ans[size++] = t + '0'; else ans[size++] = t - 10 + 'A'; tmp /= b; } for (int i = size - 1; i >= 0; i--)printf("%c", ans[i]); printf(" "); } return 0; }