【算法总结】数学问题-%运算符与取余运算

【算法总结】%运算符与取余运算

取余套路:

对取得的余数加上除数后,再对该和求除数的模,即可解决符号问题,保证取余结果恒正。(这里b是绝对值,恒大于0)

ans = (r+b)%b 

一、数位拆解

数位拆解即把一个给定的数字(如 3241)各个数位上的数字拆开,即拆成 3、 2、4、1。

例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),然后将它们依次累加即可得到该十进制值。

例4.2 又一版A+B

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;
}
二刷

例4.3 数制转换

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;
}
二刷