洛谷1010 幂次方 分治算法+掩码的应用

题目链接:https://www.luogu.com.cn/problem/P1010

题目给出一个2e4以内的数,要求把这个数分解成仅含2的幂次方的形式,下图是样例:

 由于一个数可以分成多个2的幂次方,可以将其划分为多个子问题,再对每个子问题递归求解,这就是分治算法的精髓。在本题中,分治的最小子问题就是2^0和2^1,对于其他的可以继续递归处理。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 void dfs(int n)
 4 {
 5     if(n==0)return ;
 6     int i=0;
 7     while(pow(2,i)<=n)i++;i--;//找出n中包含的最大的二次幂
 8     if(i==0)printf("2(0)");
 9     if(i==1)printf("2");//最小的子问题
10     if(i>1)
11     {
12         printf("2(");
13         dfs(i);//分解指数 
14         printf(")");
15     } 
16     n-=pow(2,i);
17     if(n)//当n还有剩余不为0的部分时,需要加+ 
18     {
19         printf("+");
20         dfs(n);
21     }
22 }
23 int main()
24 {
25     int n;
26     scanf("%d",&n);
27     dfs(n);
28 }

本题也可以利用位运算来处理,而且也非常高效,代码如下:

 1 #include<iostream>
 2 using namespace std;
 3 void mici(int n)
 4 {
 5     if(n==0)
 6     {
 7         cout<<0;//第0位是2(0); 
 8         return;
 9     }
10     if(n==1)return;//第一位只要输出2 
11     for( int i=16, mask=0x00008000, first=1;i>=1;i--)//i,mask,first都是局部变量 
12     {
13         if(mask&n)
14         {
15                 if(!first)cout<<'+';//除第一个外都要写加号 
16             cout<<2;
17             if(i!=2)cout<<"(";
18             mici(i-1);
19         
20             if(i!=2)cout<<")";
21             if(first)first=0;
22         }
23         mask>>=1;
24     }
25 }
26 int main()
27 {
28     int x;
29     cin>>x;
30     mici(x);
31 }

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/12611935.html
今日推荐