位运算与递归妙用(做洛谷P1010有感)

做了洛谷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;
}
    
发布了6 篇原创文章 · 获赞 1 · 访问量 141

猜你喜欢

转载自blog.csdn.net/qq_46015269/article/details/105588091