做了洛谷P1010,被一位大佬的思路震撼,说一下自己的想法。
位运算符号
右移位: x>>i x是被操作数,i是移位数
同理,左移位: x<<i
此外,按位与也很常用,经常用于判断各种情况。
例如
1的二进制表示为0000 0001
x=0000 0011;
y=0000 0010;
a=x&1; //1的二进制与x的二进制按位与得到a=1;
b=y&1; //1的二进制与y的二进制按位与得到b=0;
位运算是一种直接形式的数运算,比普通的数运算快了不止一个档次,在一些题目中不仅可以减少时间和空间消耗,还可以另辟捷径,优化算法结构。
位运算的理解
通俗地理解,就是把我们普通的数想象成一串二进制数据,
0000 0111 //7的二进制表示
将0000 0111进行右移一位
0000 0011 // 移位后变成3的二进制
右移就相当于整型数据除以2的n次方
int x=?;
x=x/2; 等价于 x=x>>1;
附上这道对位运算和递归都可加深理解的洛谷题:
链接:https://www.luogu.com.cn/problem/P1010
任何一个正整数都可以用 22 的幂次方表示。例如 137=27+23+2^0137=2
7
+2
3
+2
0
。
同时约定方次用括号来表示,即 a^ba
b
可表示为 a(b)a(b)。
由此可知,137137 可表示为 2(7)+2(3)+2(0)2(7)+2(3)+2(0)
进一步:
7= 22+2+207=2
2
+2+2
0
( 2^12
1
用 22 表示),并且 3=2+2^03=2+2
0
。
所以最后 137137 可表示为 2(2(2)+2+2(0))+2(2+2(0))+2(0)2(2(2)+2+2(0))+2(2+2(0))+2(0)。
又如 1315=2^{10} +2^8 +2^5 +2+11315=2
10
+2
8
+2
5
+2+1
所以 13151315 最后可表示为 2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)。
输入格式
一行一个正整数 nn。
输出格式
符合约定的 nn 的 0,20,2 表示(在表示中不能有空格)。
输入输出样例
输入 #1复制
1315
输出 #1复制
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
string f(int x,int i=0,string s="")
{
if(x==0) return "0";
do
{
if(x&1)
{
s=(i==1?"2":"2("+f(i)+")")+(s==""?"":"+")+s; 递归核心
}
i++;
}while(x>>=1);
return s;
}
int main(){
ios::sync_with_stdio(false);
cout.tie(NULL);
int n;
cin>>n;
cout<<f(n)<<endl;
return 0;
}