• 关于负数取模与负数除法取整(P1017 进制转化)


    首先,除法总是向0取整的,即2/3=0,-2/3还是0,因此可以把负号拿出来变成-(2/3).提取(除数或被除数)负号总是可行的,这还包括-2/-3,2/-3之类的情况.

    而负数的取模运算如a%b,标准规定其可由a-(a/b)*b得出,那么可知

      1.运算结果的符号与a相同.    (因为减号右侧的绝对值一定不大于a)

      2.(这意味着)b的符号不影响运算结果.    (把上式中的b换为-b,提取符合后与原式相等)

    所以对于涉及负数取模的运算a%b,如果你单纯地想要得到等价的运算结果,可以用这样的方法思考:

    • 用b的绝对值替换b
    • 把a的符号提取出来
    • 进行两正整数之间的取模,并加上a的符号

    下面这题中,需要你对负数的取模,整除进行特殊处理,如负数除以负数求正余数,负数除以负数"向下"取整.

     来看看-15转为-2进制的过程.

    不停地用-2为除数去除-15,并取余数(正数)为结果中的一位.

    -15/-2=7余1,看上去是符合的,然而此时1x(-2)4+1x(-2)3=8,不为7.

    当进行正数的进制转化时,每次除总是向下取整取余数为结果,而进行负数的进制转化时,每次除总是向0,也就是向上取整了,我们需要向下取整.

    想要这样操作只需要进行一下判断再处理就可以了.

    现在,每次除之后想要得到一个正余数,a%b若左侧数为正数,不需要额外处理,如果为负数,写为-b+a%b即可.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    char num[30] = "0123456789ABCDEFGHIJKLMN";
    
    void slove(int n, int m) {
        if (n > 0 || n % m == 0) {
            slove(n / m, m);
            putchar(num[n % m]);
        } else if (n < 0) {
            slove(n / m + 1, m);
            putchar(num[-m + n % m]);
        }
    }
    
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        printf("%d=", n);
    
        slove(n, m);
    
        printf("(base%d)", m);
    
        return 0;
    }
    P1017
  • 相关阅读:
    2015年 Stoi&Gdoi 反思总结与未来计划
    bzoj4517: [Sdoi2016]排列计数--数学+拓展欧几里得
    bzoj4518: [Sdoi2016]征途--斜率DP
    BZOJ 1391: [Ceoi2008]order
    BZOJ 2527: [Poi2011]Meteors
    BZOJ 2087: [Poi2010]Sheep
    BZOJ 1283: 序列
    BZOJ 1914: [Usaco2010 OPen]Triangle Counting 数三角形
    BZOJ 3513: [MUTC2013]idiots
    BZOJ 3771: Triple
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14436408.html
Copyright © 2020-2023  润新知