Yinchuan Regional 2019 I. Base62
Yinchuan Regional 2019
I. Base62
题目链接
I. Base62
题意:
把 x x x 进制数 z z z 转化为 y y y 进制数。
思路:
很典型的高精。需要先把 x x x 进制转化为 10 10 10 进制,再把 10 10 10 进制转化为 y y y 进制。
x
→
10
x\rightarrow10
x→10 进制的过程是:设置一个高精度
10
10
10 进制数
t
t
t 用来暂存,每次先给
t
t
t 乘以进制
x
x
x,再取出
x
x
x 进制数
z
z
z 当前的最高位,然后加入到
t
t
t,加一遍就是转化后的数。数学证明如下:假设
z
z
z 写成
x
x
x 进制数的形式为
a
i
a
i
−
1
…
a
1
a
0
a_i a_{i-1}\dots a_1 a_0
aiai−1…a1a0
t
(
10
进制
)
=
z
(
x
进制
)
=
a
i
∗
x
i
+
a
i
−
1
∗
x
i
−
1
+
⋯
+
a
1
∗
x
+
a
0
(
10
进制
)
=
(
(
…
(
(
a
i
∗
x
+
a
i
−
1
)
∗
x
+
a
i
−
2
)
∗
x
+
…
)
∗
x
+
a
1
)
∗
x
+
a
0
t(10进制)=z(x进制)=a_i*x^i+a_{i-1}*x^{i-1}+\dots+a_1*x+a_0(10进制)\\=((\dots((a_i*x+a_{i-1})*x+a_{i-2})*x+\dots)*x+a_1)*x+a_0
t(10进制)=z(x进制)=ai∗xi+ai−1∗xi−1+⋯+a1∗x+a0(10进制)=((…((ai∗x+ai−1)∗x+ai−2)∗x+…)∗x+a1)∗x+a0照着式子递推即可(其实就是秦九韶算法)。这个过程中需要用到高精加法和乘法。
10
→
y
10\rightarrow y
10→y 进制的过程是:设置一个高精度
y
y
y 进制数
t
t
t 用来暂存,然后每次除以
y
y
y,余数放入
t
t
t,最后得到的就是
y
y
y 进制数了。数学证明如下:假设要转化的
10
10
10 进制数写成
y
y
y 进制数的形式为
a
i
a
i
−
1
…
a
1
a
0
a_i a_{i-1}\dots a_1 a_0
aiai−1…a1a0
t
(
y
进制
)
=
(
(
…
(
(
a
i
∗
y
+
a
i
−
1
)
∗
y
+
a
i
−
2
)
∗
y
+
…
)
∗
y
+
a
1
)
∗
y
+
a
0
(
10
进制
)
t(y进制)=((\dots((a_i*y+a_{i-1})*y+a_{i-2})*y+\dots)*y+a_1)*y+a_0(10进制)
t(y进制)=((…((ai∗y+ai−1)∗y+ai−2)∗y+…)∗y+a1)∗y+a0(10进制)观察式子,每次除以
x
x
x 的时候,式子总是
(
…
)
∗
y
+
a
s
(\dots)*y+a_s
(…)∗y+as 的形式,余数就是
a
s
a_s
as,我们依次除出来的余数就是
a
0
,
a
1
,
a
2
,
…
,
a
i
a_0,a_1,a_2,\dots,a_i
a0,a1,a2,…,ai。这个过程需要高精除法,同时需要返回余数。
–分割线–
高精算是典型的比较顶级的模拟题目了,需要注意很多东西。这里强调几点:
- 一般高精加法和乘法只写高精运算高精,再写个低精转高精的函数就可以不用写高精运算低精的算法了。
- 高精数最好从低位开始存储,即小下标存放低位数,方便进位(毕竟没有push_front())。
- 高精数实现可以使用vector<int>,能实现动态开空间,也方便维护高精数,以下是一些常用用法(假设定义好了一个高精数叫
a
a
a):
- 返回高精数位数:
a.size()
- 进位:
a.push_back(val)
- 去除后导0:
while(a.size()>1 && a.back()==0)a.pop_back();
(和reverse(a.begin(),a.end())
共同使用可以去除前导0)
- 返回高精数位数:
code:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
int x,y;
string z;
map<char,int> mp1;
map<int,char> mp2;
void print(vector<int> t){
for(auto it=t.rbegin();it!=t.rend();it++)cout<<mp2[*it];
puts("");
return;
}
vector<int> g(int x){
vector<int> a;
do{
a.push_back(x%10);
x/=10;
}while(x);
return a;
}
vector<int> operator+(vector<int> a,vector<int> b){
int n=max(a.size(),b.size());
vector<int> c(n,0);
for(int i=0;i<n;i++)
c[i]=((i<a.size())?a[i]:0)+((i<b.size())?b[i]:0);
int ct=0;
for(int i=0;i<n;i++){
c[i]+=ct;
ct=c[i]/10;
c[i]%=10;
}
while(ct){
c.push_back(ct%10);
ct/=10;
}
return c;
}
vector<int> operator*(vector<int> a,int b){
for(int i=0;i<a.size();i++)
a[i]*=b;
int ct=0;
for(int i=0;i<a.size();i++){
a[i]+=ct;
ct=a[i]/10;
a[i]%=10;
}
while(ct){
a.push_back(ct%10);
ct/=10;
}
return a;
}
pair<vector<int>,int> operator/(vector<int> a,int b){
vector<int> c;
int tmp=0;
for(int i=a.size()-1;i>=0;i--){
tmp*=10;
tmp+=a[i];
c.push_back(tmp/b);
tmp%=b;
}
reverse(c.begin(),c.end());
while(c.size()>1 && c.back()==0)c.pop_back();
return make_pair(c,tmp);
}
vector<int> to10(string s,int p){
vector<int> t(g(0));
for(auto x:s){
t=t*p;
t=t+g(mp1[x]);
}
return t;
}
vector<int> toy(vector<int> t,int y){
vector<int> a;
do{
auto x=t/y;
t=x.first;
a.push_back(x.second);
}while(t!=g(0));
return a;
}
int main(){
for(int i=0;i<=9;i++){
mp1['0'+i]=i;
mp2[i]='0'+i;
}
for(int i=0;i<26;i++){
mp1['A'+i]=10+i;
mp2[10+i]='A'+i;
}
for(int i=0;i<26;i++){
mp1['a'+i]=36+i;
mp2[36+i]='a'+i;
}
cin>>x>>y>>z;
print(toy(to10(z,x),y));
return 0;
}
原文地址:https://blog.csdn.net/qq_45809243/article/details/136149594
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!