题解 | 幂次方-牛客假日团队赛8L题

L-幂次方_牛客假日团队赛8

https://ac.nowcoder.com/acm/contest/1069/L

题目描述

任何一个正整数都可以用2的幂次方表示。例如:                  
        
同时约定方次用括号来表示,即a可表示为
由此可知,137可表示为:

进一步:表示)

  
所以最后可表示为:

又如:

所以最后可表示为:
 

输入描述:

正整数

输出描述:

符合约定的n的0,2表示(在表示中不能有空格)

示例1

输入
1315
输出
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

解答

问题分析:
方法一:将n拆分为若干2的幂次方的和,再将各个幂次方(指数)拆分成为若干2的幂次的和……这是递归的思想。递归的边界是什么呢?指数 n=0时候 直接输出2(0),n=1的时候输出 2。如果n>1的时候 那么应该直接输出“2(“,再对指数进行递归,递归后补上括号“)”(类似回溯恢复现场) 整个递归的过程类似于深度优先搜索(DFS)。+号的处理是本题的难点 ,什么时候输出 ‘+’号呢,如果X- 2n不为0,那么说明他剩余部分也需要进行分解的,所以应该需要输出‘+’,例如 那么说明分解了7后 一定要有+号,才能把9部分的分解也加上。
#include<bits/stdc++.h>
using namespace std;
int x,a[32];
void npow(int n){
		for(int i=x;i>=0;--i){
			if(a[i]<=n){
				n=n-a[i];
				if(i>1){
					cout<<"2(";
					npow(i);       //可以理解为DFS搜索
					cout<<")";     //回溯     
				}
		       if(i==1) cout<<"2";
			   if(i==0) cout<<"2(0)"; 
			   if(n!=0) cout<<"+"; //若此n还没分解完,则后面还有项,所以输出一个+号
			}
		
		}	
}

int main()
{
	int n;
	cin>>n;
	a[0]=1;
	while(a[x]<n){
		x++;
		a[x]=a[x-1]*2;
	}
	npow(n);
	cout<<endl;
	return 0;
}

方法二:分治的思想,把一个数X分解为 进行递归求解,这样可以简单的处理好“+”号的问题。
#include<bits/stdc++.h>
 using namespace std;
string f(int x){
    if (x==1) return "2(0)";
    if (x==2) return "2";
    if (x==3) return "2+2(0)";   //防止3 输出2(2(0))+2(0);
    int n=log2(x);                      // 求出指数取整  
    int t=pow(2, n);                 
    if (x==t) return "2("+f(n)+")";              // x 恰好是 2的n次放,后面就没有了 不需要+号。
    else return "2("+f(n)+")+"+f(x-t);       //不是2的n次方,那么对2部分分别进行递归求解用+号连接
}
int main(){
    int x;
    cin>>x;
    cout<<f(x)<<endl;
}

方法三:打表法(作弊)
因为题目中数据规模是 ,所以如果 我们把指数0-14 的表示好放在一个字符串数组里面,如果来了一个数X,我们只需要把对应的幂次方直接输出即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    string s[16]={"2(0)","2","2(2)","2(2+2(0))","2(2(2))","2(2(2)+2(0))","2(2(2)+2)",
    "2(2(2)+2+2(0))","2(2(2+2(0)))","2(2(2+2(0))+2(0))","2(2(2+2(0))+2)",
    "2(2(2+2(0))+2+2(0))","2(2(2+2(0))+2(2))","2(2(2+2(0))+2(2)+2(0))",
    "2(2(2+2(0))+2(2)+2)","2(2(2+2(0))+2(2)+2+2(0))"};
    bool temp=0;
    for(int i=15;i>=0;i--)
		if(pow(2,i)<=n)
		{
		 	n-=pow(2,i);
			if(temp)
				cout<<'+';
			cout<<s[i];
			temp=1;
		}
    return 0;
	}


来源:qq_37358013
全部评论

相关推荐

有很多问题,求大佬们解答,谢谢大佬们:不知道现在该怎么投实习,该怎么准备内心很纠结学校课程和实习到底怎么选择,&nbsp;自己也不想课程学业这边出问题,&nbsp;是不是只能投暑期实习,具体时间该怎么安排前端面试也需要准备算法么,&nbsp;自己的算法能力很薄弱,&nbsp;面试题需要准备到什么程度?没有ai项目经验的话,我该如何去补充,如何去找好的ai项目
smile丶snow:1.简历尽量一页,比如教育经历那里,全日制,计算机学院这些可以去掉没啥用好浪费空间。 熟悉三件套就没必要写了吧。js基本上是这样写 * JavaScript核心:深入理解 JS 运行机制(事件循环 Event Loop、微任务/宏任务),熟练掌握 Promise/Async 异步编程 模型。 熟悉可以改成熟练掌握。组件库写一个ant感觉就行,多写了浪费空间。 旅游项目是不是jonas的natours啊,我之前简历也有这个。我之前是这样写的 全栈思维: 熟悉 Node.js/Express 后端架构,掌握 MongoDB 数据库设计与聚合查询 工程化我觉得还是少些吧,不写就问的少,如果你真的了解的话可以写。 1.实习的话推荐大厂官网和aoob上面投,我自己有写一个校招网站的小网站可以直达~github主页上面有,顺便求个关注( 2.大三下一般课程比较少了吧,如果学校比较严的话可以多沉淀一会,如果不太严可以请dai课然后去实习,尽量找个近一些的就行。暑期实习不是暑假才实习哦,基本是上3月底4月初发offer就可以过去了,然后大概暑假的时候走转正流程答辩。 3.大厂算法题+js手写体。hot100+常见的比如数组转树,Promise.all,deepClone,之类 js手写都不难其实。算法看自己能力吧,我其实算法能力也不行。 4.自己平时没有用AI Coding吗?自己想一下怎么让AI帮你更好的写代码~比如Skill的诞生,OpenSpec的诞生,不都是我们想让AI更好帮我们写代码吗。
我的实习日记
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务