题解 P1017 进制转换

Posted jelly123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P1017 进制转换相关的知识,希望对你有一定的参考价值。

我赶jio这个题难道是让我们写快写?
不管了,赶紧把咕咕咕了一万年的题解写出来。


这个题就是考察负进制和在mod意义下的除法运算的基础运算
(其实也没多大问题)
首先我们先假设一个原始数据\(num\)和基底\(base(1\leq base\leq20)\)
然后不妨设\(num=a*base+b\)(且$b = num\space mod\space a $ )
重点来了!
如果\(b<0\),我们就\(b-base,a+1\),很明显这样做是正确的。
为啥呢?因为base是负数。负数减去一个比第一个负数大的负数肯定是个正数,而且不影响后面的数字的拆开。
(恒等变换自己拆开式子便知道了)
我们其实只需要\(b\)这一个数据,让\(a*base\)留在原来剩下的num中继续递归就可以。
最后一个
窝一开始设的char[]="0123456789ABCDEF",有两个错误:

  1. 没有‘G‘
  2. 输出基本是空的(我也不知道为啥

不管了放个cpp

#include <iostream>
#include <cstdio>
#include <stack>
#include <string>

using namespace std;
//用了string类型再错就去世
string str="0123456789ABCDEFG"; 
string realans="";
//注意我使用了传址调用,直接修改num的值
char getachar(int key,int &num,const int &base)

    if (key<0)
        key-=base,num+=base;
    return str[key];//返回应该有的值

//工作函数,有点像快速输出的赶jio
void work(int num,int base)

    if (num==0)return;
    char ch=getachar(num%base,num,base);
    //先记录一下当前的字符
    //然后再直接下一层调用
    work(num/base,base);
    //最后注意将这一位上的放在原先的后面
    //短除法的精髓所在
    realans=realans+ch;


int main()

    int num,jidi;
    cin>>num>>jidi;
    work(num,jidi);
    //畅快的输出
    cout<<num<<'='<<realans<<"(base"<<jidi<<')'<<endl;
    return 0;

再放一个快速输出的板子,让读者自己感受一下qwq

//输出一个数字
template<typename T>void write(T num)

    if (num<0)putchar('-'),num=-num;
    if (num>9)write<T>(num/10);
    putchar('0'+num%10);

//特化函数
void writeln()
//输出多个数字,默认空格隔开
template<const char split=' ',class T1,class ...T2>
void writeln(T1 &num,T2 &...rest)

    write<T1>(num);
    putchar(split);
    writeln(rest...);

以上是关于题解 P1017 进制转换的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1017 进制转换

洛谷P1017 进制转换

洛谷 P1017 进制转换

[洛谷P1017] 进制转换

洛谷—— P1017 进制转换

洛谷 P1017 进制转换