目录
前言:
算法学习记录不是算法介绍,本文记录的是从零开始的学习过程(见到的例题,代码的理解……),所有内容按学习顺序更新,而且不保证正确,如有错误,请帮助指出。
学习工具:蓝桥OJ,LeetCode
背景知识:
0B 表示二进制的前缀
0O表示八进制的前缀
0x表示十六进制的前缀
正文:
任意进制转十进制:
原理:
一个K进制的数,
给它加1 == 给它个位上加1;
给它加 K == 给它十位上加1;
给它加 K*K == 给它百位上加1;
以此类推,发现一个规律:它的值(十进制)等于它的每一位数乘以它的位权。
位权就个数字,表示该单位的大小。
图解:
笔算:
举例:
机器算:
模板:
//数组a以数字形式存每一位
long long x = 0;
for(int i = 1;i <= n; i++)
{
x = x * k + a[i];
}
cout << x << endl;
十进制转任意进制:
原理:
任意一个十进制数都可以写成这样展开的形式:
笔算:
机器算:
long long x;
cin >> x;
while(x)a[++cnt] = x % k, x /= k;
reverse(a + 1, a + 1 + cnt);
//要翻转下数组,才能使得高位在正确位置
例题集:
蓝桥OJ 2489:进制
#include<iostream>
using namespace std;
const int N = 50;
int a[N];
int main()
{
string s = "2021ABCD";
for(int i = 0;i < s.length();i ++)
{
if('0' <= s[i] && s[i] <= '9')a[i + 1] = s[i] - '0';
else a[i + 1] = s[i] - 'A' + 10;
}
long long x = 0;
for(int i = 1;i <= s.length(); ++i)
{
x = x * 16 + a[i];
}
cout << x ;
return 0;
}
//另解:
//unsigned int x = 0x2021abcd;
//cout << x << endl;
蓝桥OJ 2095:九进制转十进制
#include<iostream>
using namespace std;
const int N = 10;
int a[N];
int main()
{
int n = 4;
string s = "2022";
for(int i = 1;i <= 4; ++i)a[i] = s[i - 1] - '0';
long long x = 0;
for(int i = 1;i <= n;i ++)x = x * 9 + a[i];
cout << x << endl;
return 0;
}
蓝桥OJ 1230:进制转换
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1000;
int a[N];
char ch[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
void solve()
{
int n,m; cin >> n >> m;
string s;cin >> s;
int len = s.length();
s = "#" + s;
for(int i = 0;i <= len; ++i)
{
if('0' <= s[i] && s[i] <= '9')a[i] = s[i] - '0';
else a[i] = s[i] - 'A' + 10;
}
ll x = 0;
for(int i =1;i <= len;++i)x = x * n + a[i];
string ans;
while(x){
ans += ch[x % m];
x /= m;
}
reverse(ans.begin(),ans.end());
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _;cin >> _;
while(_--){
solve();
}
return 0;
}
总结:
类似泰勒展开:不易求解的函数展开成多项式的形式。
进制转换的本质就是将一个数字按照位权展开。(位权展开法)
根据这一规律,进制转换就是展开和展开的逆过程的重复。
记忆模板:
/*进制转换*/
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int n = 100;
int a[n];
int main()
{
/*转至十进制*/
ll x = 0;
int k;cin>> k;
for(int i = 1;i <= n; ++ i)
{
x = x * k + a[i];
}
cout << x << '\n';
/*转出十进制*/
int cnt;
ll u;cin >> u;
while(u)a[++ cnt] = x % k,x/=k;
reverse(a+1,a+1+cnt);
return 0;
}