我赶 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", 有两个错误:
没有'G'
输出基本是空的 (我也不知道为啥
不管了放个 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...);
- }
来源: http://www.bubuko.com/infodetail-3086788.html