题目传送门
题目描述
对于一个十进制数A,将A转换为二进制数,然后按位逆序排列,再转换为十进制数B,我们称B为A的二进制逆序数。 例如对于十进制数173,它的二进制形式为10101101,逆序排列得到10110101,其十进制数为181,181即为173的二进制逆序数。
输入描述:
一个1000位(即10^999)以内的十进制数。
输出描述:
输入的十进制数的二进制逆序数。
输入
173
输出
181
思路
进制转换+字符串运算模板题
粗略的估算了一下,开了个3400大小的string数组,提前算好2的n次幂,难点是字符串的运算。
2 3400 > 2 3330 = 2 10 333 ≈ 1 0 3 333 = 1 0 999 2^{3400}>2^{3330}={2^{10}}^{333} ≈ {10^{3}}^{333}=10^{999} 23400>23330=210333≈103333=10999
实现了字符串与常数的乘法和除法,实现了两个string类型字符串的加法。
代码
#include <bits/stdc++.h>
using namespace std;
string twopow[3400];
int remaind;
int munum;
int addnum;
//字符串除以一个常数
string devide(string s,int x){
remaind=0;
int len=s.size();
for (int i=0;i<len;i++){
int t=s[i]-'0'+remaind*10;
s[i] = t/x+'0';
remaind = t%x;
}
int pos=0;
while (s[pos]=='0'){
pos++;
}
s=s.substr(pos);
if (s==""){
s="0";
}
return s;
}
//字符串与一个常数的乘积
string mult(string s,int x){
munum=0;
reverse(s.begin(),s.end());
int len=s.size();
for (int i=0;i<len;i++){
int t=s[i]-'0';
s[i] = (t*x+munum)%10+'0';
munum = (t*x+munum)/10;
}
while (munum!=0){
s=s+(char)(munum%10+'0');
munum/=10;
}
reverse(s.begin(),s.end());
return s;
}
//两个字符串相加
string add(string a,string b){
int alen=a.size();int blen=b.size();
if (alen<blen){
swap(a,b);
swap(alen,blen);
}
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
addnum=0;
for (int i=0;i<alen;i++){
int an=a[i]-'0';
int bn=0;
if (i<blen){
bn=b[i]-'0';
}
int ts = an+bn+addnum;
a[i]=(char)(ts%10+'0');
addnum=ts/10;
}
if (addnum){
a=a+(char)(addnum+'0');
}
reverse(a.begin(),a.end());
return a;
}
void init(){
twopow[0]="1";
for(int i=1;i<3400;i++){
twopow[i]=mult(twopow[i-1],2);
}
}
int main (){
init();
string a;
while (cin>>a){
string res="";
while (a!="0"){
a=devide(a,2);
res=(char)(remaind+'0')+res;
}
int rlen=res.size();
string ans="0";
for (int i=0;i<rlen;i++){
if (res[i]=='1'){
ans=add(twopow[i],ans);
}
}
cout<<ans<<endl;
}
return 0;
}
两个正整数字符串相加
/*********************************************************
*Function: add
*Description: 两个字符串数字相加
*Input: 需要外部定义一个进位标识addnum,传入参数为两个数字字符串
*Return: 加和后的数字字符串
*Others: 不考虑数字前的符号,不考虑浮点数
**********************************************************/
int addnum=0;
string add(string a,string b){
int alen=a.size();int blen=b.size();
if (alen<blen){
swap(a,b);
swap(alen,blen);
}
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
addnum=0;
for (int i=0;i<alen;i++){
int an=a[i]-'0';
int bn=0;
if (i<blen){
bn=b[i]-'0';
}
int ts = an+bn+addnum;
a[i]=(char)(ts%10+'0');
addnum=ts/10;
}
if (addnum){
a=a+(char)(addnum+'0');
}
reverse(a.begin(),a.end());
return a;
}
正整数字符串乘一个正整数
/*********************************************************
*Function: mult
*Description: 字符串和一个int型数字的乘积
*Input: 需要外部定义一个进位标识munum,传入参数为string类型的数字字符串和int型整数
*Return: 乘法运算后的数字字符串
*Others: 不考虑负数的情况,不考虑浮点数字符串(正整数字符串乘一个正整数)
**********************************************************/
string mult(string s,int x){
munum=0;
reverse(s.begin(),s.end());
int len=s.size();
for (int i=0;i<len;i++){
int t=s[i]-'0';
s[i] = (t*x+munum)%10+'0';
munum = (t*x+munum)/10;
}
while (munum!=0){
s=s+(char)(munum%10+'0');
munum/=10;
}
reverse(s.begin(),s.end());
return s;
}
正整数字符串除以一个正整数
/*********************************************************
*Function: devide
*Description: 正整数字符串除以一个正整数
*Input: 需要外部定义一个余数remaind,传入参数为string类型的数字字符串和int型整数
*Return: 除法运算后的数字字符串
*Others: 不考虑负数的情况,不考虑浮点数字符串(正整数字符串除以一个正整数)
**********************************************************/
string devide(string s,int x){
remaind=0;
int len=s.size();
for (int i=0;i<len;i++){
int t=s[i]-'0'+remaind*10;
s[i] = t/x+'0';
remaind = t%x;
}
int pos=0;
while (s[pos]=='0'){
pos++;
}
s=s.substr(pos);
if (s==""){
s="0";
}
return s;
}