【组合问题】-2的幂次方表示

OpenJudge - 8758:2的幂次方表示


解题思路:

(1)首先读懂题目,将一个十进制数分解成2进制,即2的几次方,表示为2(n),同时,这个n不能超过2,如果超过2了,必须再次分解成2的几次方

(2)然后发现,那不就是对每一个数都要进行分解么,先分解一遍,再扫一遍,如果有幂次方大于2的,再次分解,一层层往下钻,直到小于等于2了,返回即可,想到了DFS

(3)DFS本质上就是递归,回忆DFS的算法框架,首先确定出口,当分解的这个数num小于3的时候,return 即可

(4)再看如何得到这些分解的数呢?就是先将一个数转化为2进制,那么可以利用除2取余,逆序排列的方法,将二进制数存到一个数组中,对应的数组下标就是2的几次,然后再对下标进行判断,如果下标超过了2,并且此位置上是1的话,那么需要对这个下标继续分解。如图:

 (5)那么在每次分解的时候,可以维护一个布尔数组vis,用来存放对应的0和1,数组的下标便是对应的2的几次方,将一个数转化为二进制数并存放到vis中后,便可以从下标递减的顺序来判断元素值是否为1,如果是,判断对应的下标是否超过了2,如果没有超过,那么分类判断,如果是0或者2的话,输出2(n),如果是1的话,直接输出2.

(6)然后还涉及到一个打标记的问题,因为要输出+号,那么每次循环判断前bool flag=0,输出首部后,接下来的输出都要在前面加上+号,这样末尾就不会有加号。


#include<bits/stdc++.h>
using namespace std;

int n;

void dfs(int len,int num)
{
	if(num<3)//递归出口,如果下标小于3,返回 
	return ;
	
	bool vis[100]={0};//存放2进制数的数组 
	while(num!=0)
	{
		vis[++len]=num%2;//将二进制的余数存到vis数组中 
		num=num/2;//继续缩小2倍 
	}
	
	bool flag=0;//标记是否输出+号 
	for(int i=len;i>=0;i--)//从二进制数的下标从大到小遍历 
	{
		if(vis[i]==1)//如果元素值为1 
		{
			if(i<=2)//如果下标比3小的话 
			{
				if(i!=1)//如果不是1 
				{
					if(flag==0)
					{
						cout<<"2("<<i<<")";
						flag=1;
					}
					else
					cout<<"+2("<<i<<")";
				}
				else//如果是1的话 
				{
					if(flag==0)
					{
						cout<<"2";
						flag=1;
					}
					else
					cout<<"+2";
				}
			}
			else//如果下标大于2的话
			{
				if(flag==0)
				{
					cout<<"2(";//输出首部 
					dfs(-1,i);//继续 递归分解 
					flag=1;//打上标记 
					cout<<")";
				}
				else
				{
					cout<<"+2(";
					dfs(-1,i);
					cout<<")";
				}
			}
			
		}
	}
}
int main()
{
	cin>>n;
	dfs(-1,n);//-1表示数组的下标,因为要从下标0开始存
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值