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


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

    取余套路:

    对取得的余数加上除数后,再对该和求除数的模,即可解决符号问题,保证取余结果恒正。(这里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;
    }
    二刷
  • 相关阅读:
    C#中Dictionary的用法
    System.Timers.Timer用法
    C#中的异步调用及异步设计模式(三)——基于事件的异步模式
    C#中的异步调用及异步设计模式(二)——基于 IAsyncResult 的异步设计模式
    C#中的异步调用及异步设计模式(一)
    [你必须知道的异步编程]——异步编程模型(APM)
    strncasecmp与strcasecmp用法
    C语言之strrchr函数
    HDU 5289 Assignment (ST算法区间最值+二分)
    poj 1733 Parity game(种类并查集)
  • 原文地址:https://www.cnblogs.com/yun-an/p/11072284.html
Copyright © 2020-2023  润新知