这类题难度不大,但是比较容易出错
注意10进制转y进制特判0

x转y进制模板

思路:x进制转10进制,10进制转y进制

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main() {
  4. char s[105];
  5. int x, y;
  6. // 输入二进制字符串 和 代表的进制x 以及要转换的进制y
  7. scanf("%s%d%d", &s, &x, &y);
  8. // x进制转10进制
  9. int ans = 0;
  10. int len = strlen(s);
  11. for (int i = 0; i < len; i++) {
  12. ans = ans * x; // 注意是x
  13. if (s[i] >= '0' && s[i] <= '9') ans += (s[i] - '0'); // 注意 - '0'
  14. else ans += (s[i] - 'A') + 10; // 注意 - 10
  15. }
  16. // 10进制转y进制
  17. if (ans == 0) { // 特判0
  18. printf("0");
  19. return 0;
  20. }
  21. char out[105];
  22. int cnt = 0;
  23. while (ans > 0) {
  24. int w = (ans % y); // 注意 % y
  25. if (w < 10) out[cnt++] = w + '0'; // 注意 + '0'
  26. else out[cnt++] = (w-10) + 'A'; // 注意 - 10
  27. ans /= y; // 注意是y
  28. }
  29. for (int i = cnt - 1; i >= 0; i--) { // 注意倒序输出
  30. printf("%c", out[i]);
  31. }
  32. return 0;
  33. }

十进制和二进制

这题涉及到高精度,建议多敲几遍,体会模拟列算式的过程

  1. #define SUBMIT
  2. #include <time.h>
  3. #include <iostream>
  4. #include <cstring>
  5. using namespace std;
  6. const int N = 1005;
  7. char ori[N];
  8. int num[N], tr[N], ans[N];
  9. int main() {
  10. #ifdef SUBMIT
  11. freopen("in.txt", "r", stdin);
  12. freopen("out.txt", "w", stdout);
  13. long _begin_time = clock();
  14. #endif
  15. while (~scanf("%s", ori)) {
  16. // 记得清0
  17. memset(tr, 0, sizeof tr);
  18. memset(ans, 0, sizeof ans);
  19. // char -> int
  20. int len_ori = strlen(ori);
  21. for (int i = 0; i < len_ori; i++) {
  22. num[i] = ori[i] - '0';
  23. }
  24. // 10进制转2进制
  25. int len_tr = 0;
  26. int idx = 0;
  27. while (idx < len_ori) {
  28. tr[len_tr++] = num[len_ori - 1] % 2; // num整体除2的余数作为当前转换的结果
  29. // num除2
  30. int carry = 0;
  31. for (int i = idx; i < len_ori; i++) {
  32. int tmp = num[i] + carry;
  33. if (tmp % 2) carry = 10; // 除法,当前位余数*10加到下一位上
  34. else carry = 0;
  35. num[i] = tmp / 2;
  36. }
  37. if (num[idx] == 0) idx++; // 最高位为0,看下一位
  38. }
  39. // for (int i = len_tr - 1; i >= 0; i--) {
  40. // cout << tr[i];
  41. // }
  42. int len_ans = 1;
  43. // 因为逆序,所以从0开始,将2进制转10进制
  44. for (int i = 0; i < len_tr; i++) {
  45. ans[0] = ans[0] * 2 + tr[i];
  46. int carry = ans[0] / 10;
  47. ans[0] %= 10;
  48. // 从高位到低位,每一位都要相应乘2
  49. for (int j = 1; j < len_ans; j++) {
  50. ans[j] = ans[j] * 2 + carry;
  51. carry = ans[j] / 10;
  52. ans[j] %= 10;
  53. }
  54. // 在低位增补
  55. while (carry) {
  56. ans[len_ans++] = carry % 10;
  57. carry /= 10;
  58. }
  59. }
  60. // 逆序输出
  61. for (int i = len_ans - 1; i >= 0; i--) {
  62. cout << ans[i];
  63. }
  64. cout << endl;
  65. }
  66. #ifdef SUBMIT
  67. long _end_time = clock();
  68. printf("\n\ntime = %ld ms", _end_time - _begin_time);
  69. #endif
  70. return 0;
  71. }

负二进制

C++中对于负数的除法是向0取整,而非向下取整,在负数时会出现问题
此题还要注意0的情况

  1. #include <time.h>
  2. #include <iostream>
  3. #include <cstring>
  4. using namespace std;
  5. int ans[100];
  6. int main() {
  7. #ifdef SUBMIT
  8. freopen("in.txt", "r", stdin);
  9. freopen("out.txt", "w", stdout);
  10. long _begin_time = clock();
  11. #endif
  12. int m;
  13. while (~scanf("%d", &m)) {
  14. if (m == 0) { // 注意特判为0的情况
  15. cout << 0 << endl;
  16. continue;
  17. }
  18. int len = 0;
  19. while (m) { // C++对于负数的除法与一般设想不同,先去掉余数再除,确保整除
  20. int rest = abs(m % -2);
  21. ans[len++] = rest;
  22. m = (m - rest) / -2;
  23. }
  24. for (int i = len - 1; i >= 0; i--)
  25. cout << ans[i];
  26. cout << endl;
  27. }
  28. #ifdef SUBMIT
  29. long _end_time = clock();
  30. printf("\n\ntime = %ld ms", _end_time - _begin_time);
  31. #endif
  32. return 0;
  33. }