蓝桥杯《算法很美》第一章 位运算的奇巧淫技学习笔记C/C++【三】

位运算中进制的应用

《0~1间浮点实数的二进制表示》

 

 求十进制整数的二进制形式采用除法; 求十进制小数的二进制形式采用乘法。

/*二进制小数*/
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
using namespace std;
int main() {
    double num;
    string binary;
    binary.append("0.");
    cin >> num;
    int i;
    while(num > 0){
        //乘2
        double r = num*2;
        //判断整数部分
        if(r >= 1){
            //如果存在个位进位问题
            binary.append("1");
            //消除整数部分
            num = r - 1;
        }
        else{
            //如果不存在个位进位问题
            binary.append("0");
            num = r;
        }
        if(binary.length()>34){
            //0.不算入32位中
            cout << "ERROR" << endl;
            return 0;
        }
    }
    cout << binary << endl;
    return 0;
}

《出现了1次与出现了k次》

考虑下面的规律:

2个相同的二进制数做不进位加法,结果为0;

10个相同的十进制数做不进位加法,结果为0;

……

k个相同的k进制数做不进位加法,结果为0。

所以先将所有的数都转化为K进制,再将所有的数做K进制的不进位加法,那么最终的数就是仅有一个的那个数的K进制,最后在再转换为10进制即可。

思想是通用的,但是本代码具有局限性,只能满足k<=10的情况,如果有兴趣可自行编写k更大的情况。

/*出现了1次与出现了k次*/
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <cmath>
using namespace std;
#define MAX 100
int arr[MAX];
string str[MAX];
/*十进制转任意进制,最高位位于最右侧*/
string intToA(int n,int radix)    //n是待转数字,radix是指定的进制
{
    string ans="";
    do{
        int t=n%radix;
        if(t>=0&&t<=9)    ans+=t+'0';
        else ans+=t-10+'a';
        n/=radix;
    }while(n!=0);    //使用do{}while()以防止输入为0的情况
    //reverse(ans.begin(),ans.end());
    return ans;
}
int main() {
    int K,NUM;
    /*出现了K次*/
    cin >> K;
    /*总个数,必须为nK+1,n是正整数*/
    cin >> NUM;
    int i;
    int max_length = 0;//记录最多要加多少列
    /*转换为K进制*/
    for(i=0; i<NUM; i++){
        cin >> arr[i];
        str[i] = intToA(arr[i],K);
        if(max_length < str[i].length()){
            max_length = str[i].length();
        }
        cout << str[i] << "+" << str[i].length() << " ";
    }
    cout << endl <<max_length <<endl;
    /*不进位加法*/
    int j;
    int sres[max_length];
    memset(sres,0,sizeof(sres));
    for(i=0; i<NUM; i++){
        for(j=0; j<max_length; j++){
            if(j >= str[i].length() )
                sres[j] += 0;
            else{
                sres[j] += (str[i][j] - '0');
                sres[j] %= K;
            }
            cout << sres[j] << " " ;
        }
    }
//    for(i=0; i<max_length; i++){
//        cout << sres[i] << " " ;
//    }
    cout << endl;
    /*K进制转十进制*/
    int res = 0;
    for(i=0; i<max_length; i++){
        res += sres[i] *((int)(pow(K,i)));
    }
    cout << res << endl;
//    string ans = intToA(8,2);
//    cout << ans <<endl;
    return 0;
}

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值