目录
1281:【基础】求 2+2×2+2×2×2+⋯+2×2×2×⋯×2
解法一:分别判断 n%16 结果在 0~9 及 10~15 的哪个范围,分别转换为对应的字符
解法二:用字符串存储十六进制对应的字符,简化 16 进制转为字符的过程
1268:【基础】高精度加法
#include <bits/stdc++.h>
using namespace std;
/*
第一步:用 string 读入高精度整数
第二步:将两个高精度整数逆序存入 a、b 两个整数数组
第三步:从左向右,逐位求和,结果存入 c 数组从左向右,逐位进位
第四步:逆序输出结果
*/
string s1, s2;//高精度整数
int a[250], b[250], c[500];
int i, j, len;
int main(){
cin >> s1 >> s2;
//第二步:将两个高精度整数逆序存入 a b 两个整数数组
for (i = 0; i < s1.size(); i++){
a[s1.size()-i-1] = s1[i]-'0';
}
for (i = 0; i < s2.size(); i++){
b[s2.size()-i-1] = s2[i]-'0';
}
//第三步:从左向右,逐位求和,结果存入 c 数组
// 从左向右,逐位进位
//加法的次数,取决于两个整数的较长的字符串
len = s1.size();
if (s2.size() > s1.size()){
len = s2.size();
}
//逐位相加
for (i = 0; i < len; i++){
c[i] = a[i] + b[i];
}
//逐位进位
for (i = 0; i < len; i++){
if (c[i] >= 10){
c[i+1] = c[i+1] + c[i] / 10;
c[i] = c[i] % 10;
}
}
//第四步:逆序输出结果
//两个不超过 len 位的整数做加法,结果可能是 1en+1 位
if (c[len] != 0){
len++;
}
//逆序输出结果
for (i = len - 1; i >= 0; i--){
cout << c[i];
}
}
1269:【基础】高精度减法
#include <bits/stdc++.h>
using namespace std;
/*
第一步:判断 s1 和 s2 的大小关系
第二步:将两个字符串逆序存入 2 个整数数组
第三步:从左至右,逐位相减,不够借位
第四步:从右向左,逆序输出
*/
string s1, s2;
int a[250], b[250], c[250];
int i, len, p;
char f = '+';//表示结果的正负
int main(){
cin >> s1 >> s2;
//字符串长的数值更大,一样长字典码大的一定大;
if (s1.size() < s2.size() || (s1.size() == s2.size() && s1 < s2)){
f = '-';
swap(s1, s2);//直接交换两个变量的值
}
//将s1和s2逆序存入整数数组
for (i = 0; i < s1.size(); i++){
a[i] = s1[s1.size()-i-1] - '0';
}
for (i = 0; i < s2.size(); i++){
b[i] = s2[s2.size()-i-1] - '0';
}
//逐位相减
len = s1.size();
for (i = 0; i < len; i++){
//如果不够减,向右借 1,当 10 用
if (a[i] < b[i]){
a[i+1] = a[i+1] - 1;
a[i] = a[i] + 10;
}
c[i] = a[i] - b[i];
}
//判断是否要输出负号
if (f == '-') cout << f;
//从右向左逐位输出,从第一个遇到的非 0 元素开始输出
for (i = len - 1; i >= 0; i--){
if (c[i] != 0){
p = i;
break;
}
}
//逆序从第一个非 0 元素输出每一位
for (i = p; i >= 0; i--){
cout << c[i];
}
}
1280:【基础】求 2 的 n 次方
#include <bits/stdc++.h>
using namespace std;
int a[100] = {1};
//k 代表 a 数组元素的个数,代表了高精度的整数的位数
int i, j, k = 1, n;
int main(){
cin >> n;//循环 n 次,每次都将 a 数组 * 2
for (i = 1; i <= n; i++){
//将 a 数组的每一位都 * 2
for (j = 0; j < k; j++){
a[j] = a[j] * 2;
}
//逐位进位
for (j = 0; j < k; j++){
if (a[j] >= 10){
a[j+1] = a[j+1] + a[j] / 10;
a[j] = a[j] % 10;
}
}
//判断 a 数组是否多出一位
if( a[k] != 0){
k++;
}
}
//逆序输出 a 数组的 k 个数
for(i = k - 1; i >= 0; i--){
cout << a[i];
}
}
1281:【基础】求 2+2×2+2×2×2+⋯+2×2×2×⋯×2
#include <bits/stdc++.h>
using namespace std;
int a[100] = {1};
int r[1000];
//k 代表 a 数组元素的个数,代表了高精度的整数的位数
//k2 代表了高精度的总和的位数
int i, j, k = 1, n, k2 = 1, len;
int main(){
cin >> n;//循环 n 次,每次都将 a 数组 * 2
for (i = 1; i <= n; i++){
//将 a 数组的每一位都 * 2
for (j = 0; j < k; j++){
a[j] = a[j] * 2;
}
//逐位进位
for (j = 0; j < k; j++){
if (a[j] >= 10){
a[j+1] = a[j+1] + a[j] / 10;
a[j] = a[j] % 10;
}
}
//判断 a 数组是否多出一位
if ( a[k] != 0){
k++;
}
//求出了 2 的 i 次方,结果为 k 位
//将 k 位的 2 的 i 次方,加到 k2 位的总和 r 上
len = k;
if (k2 > k) len = k2;
for (j = 0; j < len; j++){
r[j] = r[j] + a[j];
//进位
if (r[j] >= 10){
r[j+1] = r[j+1] + r[j] /10;
r[j] = r[j] % 10;
}
//判断 r 数组是否多了 1 位
if (r[k2] != 0) k2++;
}
}
//输出 r 数组的结果
for (i = k2 - 1; i >= 0; i--){
cout << r[i];
}
}
1285:【基础】计算 N 的阶乘
1286:【基础】高精度乘单精度
#include <bits/stdc++.h>
using namespace std;
/*
第一步:将高精度整数 s1,逆序存入整数数组 a
第二步:将 a 数组的每一位,逐位和整数 b 相乘,结果存入 a 数组
第三步:逐位进位
第四步:逆序输出
*/
string s1;//高精度整数
int a[250], c[250], p;
int b, len;
int main(){
cin >> s1 >> b;
//第二步:将 s1 逆序存入 a 数组
for (int i = 0; i < s1.size(); i++){
a[s1.size()-i-1] = s1[i]-'0';
}
//第三步:逐位相乘
//乘法的次数,取决于符串长度
len = s1.size();
for (int i = 0; i < len; i++){
c[i] = a[i] * b;
}
//逐位进位
//结果的最大可能长度为高精度数值位数+单精度数值位数-1
//该题中单精度数值最大是 10000,即 s1*b 最多多出 4 位
for (int i = 0; i < len + 4; i++){
if (c[i] >= 10){
c[i+1] = c[i+1] + c[i] / 10;
c[i] = c[i] % 10;
}
}
//第四步:逆序输出,从第一个非 0 元素开始输出
for (int i = len + 3; i >= 0; i--){
if (c[i] != 0){
p = i;
break;
}
}
for (int i = p; i >= 0; i--){
cout << c[i];
}
}
1287:【基础】高精度乘
#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[250], b[250], c[500];
int p;
int main(){
cin >> s1 >> s2;
//将 s1 和 s2逆序输入数组
for (int i = 0; i < s1.size(); i++) {
a[i] = s1[s1.size()-i-1]-'0';
}
for (int i = 0; i < s2.size(); i++) {
b[i] = s2[s2.size()-i-1]-'0';
}
//逐位乘(进位)
for (int i = 0; i < s1.size(); i++){
for (int j = 0; j < s2.size(); j++){
c[i+j] = c[i+j] + a[i] * b[j];
//进位
if (c[i+j] >= 10){
c[i+j+1] = c[i+j+1] + c[i+j] / 10;
c[i+j] = c[i+j] % 10;
}
}
}
//逆序输出,从第一个非 0 元素输出
for (int i = s1.size() + s2.size() - 1; i >= 0; i--){
if (c[i] != 0){
p = i;
break;
}
}
for (int i = p; i >= 0; i--){
cout << c[i];
}
}
1288:【入门】正整数 n 转换为 8 进制
#include <bits/stdc++.h>
using namespace std;
int main(){
long long n;
string s;
char c;
cin >> n;
//除 8 取余
while (n != 0){
c = n % 8 + '0';
n = n / 8;
s = c + s;
}
if (s == ""){
cout << 0;
}else{
cout << s;
}
}
1289:【入门】正整数 N 转换为 16 进制
解法一:分别判断 n%16 结果在 0~9 及 10~15 的哪个范围,分别转换为对应的字符
#include <bits/stdc++.h>
using namespace std;
/*
n是一个不超过 18 位的正整数
*/
long long n, x;
string s;
char c;
int main(){
cin >> n;
while (n != 0){
x = n % 16;
//cout<<x<<endl;
//将 x 转换为字符逆序存入字符串 s
//x:0~9 ->'0'~'9'
//x:10~15 ->'A'~'F'
if (x < 10){
c = x + '0';
}else{
c = x + 'A' - 10;
}
s = c + s;
n = n / 16;
}
if (s == ""){
cout << 0;
}else{
cout << s;
}
}
解法二:用字符串存储十六进制对应的字符,简化 16 进制转为字符的过程
#include <bits/stdc++.h>
using namespace std;
/*
n是一个不超过 18 位的正整数
*/
long long n, x;
string s;
string t = "0123456789ABCDEF";
int main(){
cin >> n;
while (n != 0){
x = n % 16;
//cout << x << endl;
//将 x 转换为字符逆序存入字符串 s
//x:0~9 ->'0'~'9'
//x:10~15 ->'A'~"F
//将 n%16 转换为字符逆序存入 s
s = t[x] + s;
n = n / 16;
}
if (s == ""){
cout << 0;
}else{
cout << s;
}
}
1290:【入门】二进制数转换十进制
#include <bits/stdc++.h>
using namespace std;
string s;//存放二进制
int r, t = 1, i;//t:表示权重
int main(){
cin >> s;
for (i = s.size() - 1; i >= 0; i--){
r = r + (s[i] - '0') * t;
t = t * 2;
}
cout << r;
}
1291:【入门】八进制转十进制
#include <bits/stdc++.h>
using namespace std;
int main(){
string x;
long long r = 0;
long long t = 1;
cin >> x;
for (int i = x.size() - 1; i >= 0; i--){
r = r + (x[i]-'0') * t;
t = t * 8;
}
cout << r;
}
1292:【入门】十六进制转十进制
#include <bits/stdc++.h>
using namespace std;
string s;
long long r, t = 1, i;//t:表示权重,也就是 16 的 i 次方
int main(){
cin >> s;
//逆序计算,按权展开
for (i = s.size() - 1; i >= 0; i--){
//如果 s[i] 是 '0'~'9'
if (isdigit(s[i])){
r = r + (s[i] - '0') * t;
}else{
//如果 s[i] 是'A'~'F'
r = r + (s[i] - 'A' + 10) * t;
}
t = t * 16;
}
cout << r;
}
1294:【基础】二进制转十六进制
# include <bits/stdc++.h>
using namespace std;
//将 4 位的 2 进制 转换为 1 位的 16 进制
char num(string s){
//从最低位开始按权展开,将 2 进制转换为十进制
//再转换为 16 进制
int r = 0, t = 1;
for (int i = s.size()-1; i >= 0; i--){
r = r + (s[i] - '0') * t;
t = t * 2;
}
char c;//存储 1 位的 16 进制字符
if (r < 10) {
c = r + '0';
}else{
c = r + 'A' - 10;
}
return c;
}
int main(){
string s, t;//存放二进制
cin>>s;
//补 0
if (s.size() % 4 == 1){
s = "000" + s;
}else if (s.size() % 4 == 2){
s = "00" + s;
}else if (s.size() % 4 == 3){
s = "0" + s;
}
// 每 4 位一格,将 4 位的二进制转换为 16 进制
for (int i = 0; i < s.size(); i = i + 4){
t = s.substr(i, 4);
cout << num(t);
}
}