算法很美-位的奇巧淫计(c/c++)

用一个整数判断是不2的整数次方

-----换句话说就是,判断2进制中1的个数是不是只有一个

2---10           4-100 

 8--- 1000   7 --0111  (n和n-1&的结果0) 

6 ---110   5 ---101  (7的结果是1)

只有2次方的结果&才是0

代码如下

#include<bits/stdc++.h>
using namespace std;
 int main(){
 	int n ;
	cin>>n;
	if(n>0&&((n & (n -1)) ==0)){
		cout<<"yes";
	}else{
		cout<<"no";
	}	
 	return 0;
 }

当然,比较容易想到的就是对n取余 

	while(!(n%2)){
		n = n/2;
		if(n==1){
			cout<<"yes";
			return 0;
		}
	}
	cout<<"no" ;

将整数的奇偶位互换

异或运算:相同为0 不同为1

相与运算:只有1&1=1其他情况全都为0

简单举例:9 --1001   ------0110--->6

用0 &就是消除,用1&就是保留原来的

思路来源:https://blog.csdn.net/etalien_/article/details/81179164

将一个二进制数(最后一位默认为第一位 也就是奇数位)的奇数位提取出来,像左移动一位,数的偶数位提取出来,向右移动一位,进而做异或,就可得到交换后的结果

1001

奇数提取 0001 左移 0010   

偶数提取 1000 右移 0100

进行异或或者进行相加  0110

现在问题在于,如何进行奇偶位的提取:

用0 &就是消除,用1&就是保留原来的

奇数位: 奇数不变,偶数清0,那就让奇数位与1相与,偶数位与0相与:

                 这个二级制序列为   0101 0101 0101 0101 0101 0101 0101 0101===》0x55555555

同理偶数位:偶数不变,奇数清0, 那就让奇数位与0相与,偶数位与1相与:

                 这个二级制序列为  1010 1010 1010 1010 1010 1010 1010 1010 ===》0xAAAAAAAA

代码如下:

#include<bits/stdc++.h>
using namespace std;
 int main(){
 	int n ;
	cin>>n;
	int tmp = ((((n)&0x55555555)<<1)+(((n)&0xAAAAAAAA)>>1));
	cout<<tmp;	
 	return 0;
 } 

乘2挪整二进制表示浮点实数:

题目:给定一个介于0和1之间的实数(如 0.625)类型为double,打印他的二进制表示0.101
如果该数字无法精确地用32为以内的二进制表示默认error

需要注意的是:小数点后的二进制分别表示 0.5 、0.25、 0.125, 位向左移表示乘2,右移表示除2

这里与整数的8421规则类似又不同, 她是乘2,如果结果>=1, 表示的二进制数后写1 ,

                                                                              乘2后<1, 表示的二进制数后写0;

      举例子:0.625*2 =1.25==>0.1---------0.25

                  0.25*2 = 0.5==>0.10------------0.5

               0.5*2 = 1.0==>0.101----------------------0

#include<bits/stdc++.h>
#include<string.h>
#include <iostream> 
using namespace std;
 int main(){
 	double n ;
 	int count = 32;
	cin>>n;
	string a ="0.";
	while(n>0&&count--){
		n = n*2;
		int t = n; //n是double类型,int之后只剩整数,就可以判断,整数位示0还是1
		 
		n =n-t; //将整数位抹去 ,继续进行*2 
		a+=(t+48); //ascll码从0开始是48 
	}	
	if(count>0){
			cout<<a<<endl;
	}else{
		cout<<"error";
	}
	 	return 0;
 } 

出现k次与出现一次:

题目:数组中只有一个数出现了1次,其他数都出现了k次,请输出,只出现一次的那个数

比较直接的就是暴力破解,进行计数排查

一个技巧点:2个2进制相加且不进位的结果为0,10个10进制的数相加不进位 结果为0

总结来说就是:k个k进制数相加不进位的结果为0;

本题思路,所有数进行k进制转换,然后做k进制的不进位加法,结果为0 ,进行排除,剩下的就是答案的k进制,然后再转成10进制

                  难点1:十进制转k进制 在java中integer.tostring(i,k);

                 难点2: k进制转十进制  a*k的(几次方)+ a*k的(1方)+a*k的(0方)

                 难点3:不进位加法:相加之后和 对k 取余,结果就是对应位上数值

代码:待完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特立独行的蜗牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值