算法学习专栏——进制转换类型题目
位运算
按位与(&)
计算方式:
有0出0,全1出1
例如:
4&5改为二进制
4 –> 0000 0100
5 –> 0000 0101
0000 0100 <–4
因此4&5=4
按位或(|)
计算方式:
有1出1,全0出0
例如:
4&5改为二进制
4 –> 0000 0100
5 –> 0000 0101
0000 0101 <–5
因此4|5=5
按位异或(^)
计算方式:
相同为0,不同为1
例如:
4&5改为二进制
4 –> 0000 0100
5 –> 0000 0101
0000 0001 <–1
因此4^5=1
用途:交换变量
1 |
|
取反(~)
计算方式:
二进制中的1变0,0变1
位运算符(>> 和 <<)
计算方式:
将一个数的二进制位全部左移(右移)若干位
左移:高位溢出不用,低位补0
右移:低位溢出不用,高位正数补0,负数补1
左移一位相当于乘2,2^n^相当于左移n位,右移同理
例子:
a = 10 = (1010)2
a = a << 2 =(1000)2
一、数的进制转换(—)(简单-)
大家好,我是小刘,现在我正在学习计算机的基础知识:进制转换,但是现在有个问题,我发现学校交给我们进制转换仅仅是2、8、10、16进制之间的转换,现在我想设计一段代码,可以实现任何进制数对任何进制数之间的转换。
注意:字母这里可能为大小写字母,不需要考虑大小写问题,比如Ab23。
输入格式
输入一个字符串 X,X的进制为Y,需要转化为的进制为Z。
输出格式
输出转换为Z进制的数X的格式。
数据范围
$$
1 <= X.length() <= 5\
2<=Y<=36\
2<=Z<=36
$$
输入样例1:
1 |
|
输出样例1:
1 |
|
输入样例2:
1 |
|
输出样例2:
1 |
|
思路
思路
可以选择先将这个数转换为10进制,再将其转换为对应进制,这个思路是最常见最简单的一套思路
代码
答案(请自己先思考一下再参考)
#include < iostream> #include < algorithm> #include < vector> using namespace std; string x; int y,z; int k = 1; long long ans; vector C; int main() { cin >> x >> y >> z; for (int i = x.size() - 1; i >= 0; i--) { if (x[i] >= 'A' && x[i] <= 'Z') ans += (x[i] - 'A' + 10) * k; if (x[i] >= 'a' && x[i] <= 'z') ans += (x[i] - 'a' + 10) * k; else ans += (x[i] - '0') * k; k *= y; } // 下面这种写法也可以 //for (int i = x.size() - 1; i >= 0; i--) //{ // x[i] = tolower(x[i]); // 这个函数的作用是将字母转换为小写字母,比如'A'变为'a', // if (x[i] >= 'a' && x[i] <= 'z') ans += (x[i] - 'a' + 10) * k; // else ans += (x[i] - '0') * k; // k *= y; //} while (ans){ C.push_back(ans % z); ans /= z; } for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; return 0; }
二、数的进制转换(二)(简单)
编写一个程序,可以实现将一个数字由一个进制转换为另一个进制。
这里有 62 个不同数位 **{0−9,A−Z,a−z}{0−9}**。
输入格式
第一行输入一个整数,代表接下来的行数。
接下来每一行都包含三个数字,首先是输入进制(十进制表示),然后是输出进制(十进制表示),最后是用输入进制表示的输入数字,数字之间用空格隔开。
输入进制和输出进制都在 22 到 6262 的范围之内。
(在十进制下)A=10,B=11,…,Z=35,a=36,b=37,…,z=61 (0−9 仍然表示 0−9)。
输出格式
对于每一组进制转换,程序的输出都由三行构成。
第一行包含两个数字,首先是输入进制(十进制表示),然后是用输入进制表示的输入数字。
第二行包含两个数字,首先是输出进制(十进制表示),然后是用输出进制表示的输入数字。
第三行为空白行。
同一行内数字用空格隔开。
输入样例:
1 |
|
输出样例:
1 |
|
思路
和上一道题目思路几乎一致
代码
答案(请自己先思考一下再参考)
#include #include < algorithm> #include < cstring> using namespace std; const int Max = 1100; #define fir(a,b,c) for (int a = b;a <= c;a++) int t[Max],A[Max],n,m,i,len,k; char str1[Max], str2[Max]; void solve() { k=0; len = strlen(str1); for(i=len; i >= 0; i--) t[len - i - 1] = str1[i] -(str1[i]<58 ? 48: str1[i]<97 ? 55: 61);//开始转换成为十进制 while(len) { //这个写法大家 for(i = len; i >= 1; i--) { t[i - 1] +=t[i] % m * n;//开始计算,首先*n,为n进制,然后转移到m进制 t[i] /= m;//当前数已经处理完了 } A[k++] = t[0] % m;//直接加到答案数组中 t[0] /= m;//当前数已经处理完了 while(len > 0&& !t[len - 1]) //处理0的情况 len--; } str2[k] =NULL;//第k位,我们不需要,直接抛去,利用NULL这个特殊的字符串结束符,具体可以自行百度. fir(i,0,k - 1)//这里使用这个写法就是让大家熟悉一下,之后使用这个方法可以简化代码 str2[k - 1 - i] = A[i]+(A[i] < 10 ? 48: A[i] < 36 ? 55:61);//三目运算符,这段代码的意思是, // 找这个数字对应的字母 } int main() { int t; scanf("%d\n",&t); while(t--) { scanf("%d %d %s\n",&n,&m,str1); solve(); printf("%d %s\n%d %s\n\n",n,str1,m,str2); } return 0; }
三、数列(简单)
给定一个正整数 k,把所有 k 的方幂及所有有限个互不相等的 k 的方幂之和构成一个递增的序列,例如,当 k=3 时,这个序列是:
1,3,4,9,10,12,13,…
该序列实际上就是:3^0^,3^1^,3^0^+3^1^,3^2^,3^0^+3^2^,3^1^+3^2^,3^0^+3^1^+3^2^……
请你求出这个序列的第 N 项的值(N 用 10 进制数表示,从 1 开始)。
例如,对于 k=3,N=100正确答案应该是 981。
输入格式
输入文件只有 11 行,为 22 个正整数,用一个空格隔开:k,N,。
输出格式
输出文件为计算结果,是一个正整数(在所有的测试数据中,结果均不超过 2.1×1092.1×109)。(整数前不要有空格和其他符号)。
数据范围
$$
3≤k≤15\
10≤N≤1000
$$
输入样例:
1 |
|
输出样例:
1 |
|
思路
思路
这道题目实质上就是一个扩展思维类型题目,大家可以仔细观察一下题目给出的一串数列,然后再结合二进制来看一下就不难看出就是一个从1~n的二进制数的排列罢了,比如说:对于数字9而言对应二进制位1001,那么我们对应数列的项就是3^0 + 3^3。
代码
答案(请自己先思考一下再参考)
#include < iostream> #include < cmath> using namespace std; typedef long long LL; int k, n; LL ans; int main() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin >> k >> n; for (int i = 0; i < 15;i ++) { if ((n >> i) & 1) { ans += pow(k, i); } } cout << ans; return 0; }