1.进制转换
了解数制
数制是一种用一组固定的符号和统一的规则来表示数值的方法。包含两个基本要素:基数和位权
基数表示数制中使用的数字符号的个数。
位权表示每个位置上数字的价值。
常见的进制
常见的进制转换
任意进制转十进制C++
#include<iostream>
#include <cmath>
using namespace std;
int p, sum, tmp;
int main() {
string s;
cin >> s;
cin>>p;
int m;
for (int i= s.length()-1;i >= 0;i--) {
if (s[i] >= 'A' && s[i] <= 'F') {//如果为字母,要转换成其代表的数m=s[i]-'A'+ 10;
m = s[i] - 'A' + 10;
}
else {
m = s[i] - '0'; //小于10,转换成数字
sum += m * pow(p,tmp); //乘以位权,然后相加。
tmp++;
}
}
cout << sum;
return 0;
}
十进制转任意进制
//十进制转任意进制
#include<bits/stdc++.h>
using namespace std;
int n,p;
string s;
int main(){
cin>>n>>p;
while(n){
int tmp=n%p;
if(tmp>=10){
s+=tmp-10+'A';//大于等于10的话进行字符进制转换
}else{
s+=tmp+'0';//否则直接加0变正常字符数字
}
n/=p;//按照二进制短除法,除以p更新进制。
}
for(int i=s.length()-1;i>=0;i--){
cout<<s[i];
}
return 0;
}
任意进制互相转换
思路:
可以把十进制当作中介,先从任意进制转为十进制,再从十进制转为任意进制。(集合两个的思路)
//任意进制相互转换
#include<bits/stdc++.h>
using namespace std;
int p,q,sum,tmp;
string a,ans;
int main(){
cin>>p>>a>>q;
int m;
for (int i= a.length()-1;i >= 0;i--) {
if (a[i] >= 'A' && a[i] <= 'F') {//如果为字母,要转换成其代表的数m=s[i]-'A'+ 10;
m = a[i] - 'A' + 10;
}
else {
m = a[i] - '0'; //小于10,转换成数字
sum += m * pow(p,tmp); //乘以位权,然后相加。
tmp++;
}}
while(sum){
int tmp=sum%p;
if(tmp>=10){
ans+=tmp-10+'A';//大于等于10的话进行字符进制转换
}else{
ans+=tmp+'0';//否则直接加0变正常字符数字
}
sum/=p;//按照二进制短除法,除以p更新进制。
}
for(int i=ans.length()-1;i>=0;i--){
cout<<ans[i];
}
return 0;
}
2.位运算
位运算就是基于整数的二进制表示进行的运算。由于计算机内部就是以二进制来存储数据,位运算是相当快的。
基本的位运算共5种,分别为按位与、按位或、按位异或、按位取反、左移和右移。
位运算简介:
有关2的幂的运算的应用
将一个数乘(除)以2的非负整数次幂(向下取整)
int mul_pow(int n,int m){
return n<<m;
}
int dev_pow(int m,int n){
return n>>m;
}
3.快速幂
快速幂算法的核心思想就是每一步都把指数分成两半,而相应的底数做平方运算。这样不仅能把非常大的指数给不断变小,所需要执行的循环次数也变小,而最后表示的结果却一直不会变。
让我们先来看一个简单的例子:(来自百度百科)
3^10=3*3*3*3*3*3*3*3*3*3
3^10=(3*3)*(3*3)*(3*3)*(3*3)*(3*3)
3^10=(3*3)^5
3^10=9^5
9^5=(9^4)*(9^1)
9^5=(6561^1)*(9^1)
以下以求a的b次方来介绍
把b转换成二进制数。
该二进制数第i位的权为
例如
11的二进制是1011
因此,我们将a¹¹转化为:
快速幂的优势,给出一个例子:
问:
那么我们的暴力算法:
简单优化:利用取模性质,每次相乘就进行取模。
他的时间复杂度依旧没有优化:
这里用到我们刚才说到的快速幂。
红色为当底数的指数为偶数时,那么直接乘以底数的二倍,指数减半
黄色为当底数的指数为奇数时,需要先拿出一个底数,指数减一,然后对剩余的偶数指数进行底数相乘,指数减半。
模板代码c++
//快速幂
#include<iostream>
using namespace std;
typedef long long ll;
ll fast_power(int a,int b,int c){
ll ans=1;
a=a%c;
while(b){
if(b&1){
ans=(ans*a)%c;
}
a=(a*a)%c;
b>>=1;
}
return ans;
}
int main(){
ll a,b,c;
cin>>a>>b>>c;
cout<<a<<"^"<<b<<" mod "<<c<<"="<<fast_power(a,b,c);
return 0;
}