十六进制转八进制--蓝桥练习

本文介绍了一种高效算法,用于将长十六进制数转换为八进制数,解决了传统转换方法在大数据量下无法处理的问题。通过使用二进制作为中间转换媒介,避免了整型数据溢出,确保了算法的正确性和稳定性。

问题描述

给定n个十六进制正整数,输出它们对应的八进制数。

输入格式

输入的第一行为一个正整数n (1<=n<=10)。

接下来n行,每行一个由0-9、大写字母A-F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式

输出n行,每行为输入对应的八进制正整数。

【注意】

输入的十六进制数不会有前导0,比如012A。

输出的八进制数也不能有前导0。

样例输入

2

39

123ABC

样例输出

71

4435274

【提示】

先将十六进制数转换成某进制数,再由某进制数转换成八进制。

思路: 起初在做的时候先用的是常规的方式,写进制转换的函数将十六进制转换为十进制,再将十进制转换为八进制。后来发现题目中给的范围太大了,100000长度的十六进制用整型无法存储计算。后来用二进制作转换的媒介的方式才算是做出了这道题。
例如进制转换表

十六进制二进制八进制
00000000
10001001
20010010
30011011
40100100
50101101
60110110
70111111
81000
91001
101010
111011
121100
131101
141110
151111
#include <iostream>
#include <string>
using namespace std;
int main()
{
 int i,j,n;
 string a="";
 string b[16]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
 string c[9]={"000","001","010","011","100","101","110","111"};
 string d="";
 string e="";
 string str;
 cin>>n;
 while(n--)
 {
  cin>>a;
  for(i=0;i<=a.size()-1;i++)
  {
   if(a[i]>='0'&&a[i]<='9')
   {
    d+=b[a[i]-'0'];
   }
   else {
    d+=b[a[i]-'A'+10];
   }
  }
  for(i=d.size()-1;i>=0;i=i-3)
  {
   str="";
   if(i==0)
   {
    str+='0';
    str+='0';
    str+=d[i];
   }
   else if(i-1==0)
   {
    str+='0';
    str+=d[i-1];
    str+=d[i];
   }
   else {
   str+=d[i-2];
   str+=d[i-1];
   str+=d[i];
  }
   for(j=0;j<8;j++)
   {
    if(str==c[j])
    {
     e+=(j+'0');
     break;
    }
   }
  }
  for(i=e.size()-1;i>=0;i--)
  {
   if(i==e.size()-1&&e[i]=='0')
   {
    continue;
   }
   cout<<e[i];
  }
  cout<<endl;
  a="";
  d="";
  e="";
  
 }
 return 0;
 
 
 
}

样例输入:
B441E2411DC709E111C7E1E7ACB6F8CAC0BB2FC4C8BC2AE3BAAAB9165CC458E199CB89F51B135F7091A5ABB0874DF3E8CB45
样例输出:
13210170440435616047410434374171726266761453005662770462136052707352525621313461054341463456117521542327670221513256604164676372145505

已知蓝桥杯相关题目涉及小明用空白牌凑套牌的情境,有\(n\)张卡牌,每种各一张为一套牌,小明有\(m\)张空白牌可写数当作第\(i\)种牌,且第\(i\)种牌最多手写\(b_i\)张。但仅这些信息未明确最大卡牌价值的具体定义和规则,假设要凑出最多套牌,以下是一种可能的C语言实现思路及代码示例: ```c #include <stdio.h> #define MAX_N 100 // 检查在当前手写牌数量限制下,是否能凑出 target 套牌 int canMakeSets(int n, int m, int b[], int target) { int usedBlanks = 0; for (int i = 0; i < n; i++) { if (target > b[i]) { usedBlanks += target - b[i]; } } return usedBlanks <= m; } // 二分查找最大能凑出的套牌数 int findMaxSets(int n, int m, int b[]) { int left = 0, right = 1000000; // 假设最大套牌数不会超过 1000000 int result = 0; while (left <= right) { int mid = left + (right - left) / 2; if (canMakeSets(n, m, b, mid)) { result = mid; left = mid + 1; } else { right = mid - 1; } } return result; } int main() { int n, m; int b[MAX_N]; // 输入卡牌种类数 n 和空白牌数量 m scanf("%d %d", &n, &m); // 输入每种牌最多手写的数量 for (int i = 0; i < n; i++) { scanf("%d", &b[i]); } // 计算最大能凑出的套牌数 int maxSets = findMaxSets(n, m, b); // 输出结果 printf("最大能凑出的套牌数: %d\n", maxSets); return 0; } ``` 上述代码通过二分查找的方法,不断尝试可能的套牌数量,检查在当前手写牌数量限制和空白牌数量下是否能够凑出该数量的套牌,最终找到最大能凑出的套牌数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值