【规律】【贪心】【数学】HDU 5573 Binary Tree
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5573
题目大意:
从1走到第k层,下一层的数是上一层的数*2或者*2+1,可以选择加上或者减去走的数,最终要求结果为n
输出每层走的数,和是加还是减
题目思路:
【规律】【贪心】【数学】
首先苦思冥想一下,发现,1 2 4 8...2k可以凑成任意的奇数。而偶数只需要把2k变为2k+1。
(从k往1位考虑加减,把+看为1,-看为0,则1+2+4+...=2k-1,符号可以用二进制数X表示,为1111111...,每次X-1,则原式的答案-2)
(如+1+2+4+8=24-1=15,X=1111,则当X=1110时,表示-1+2+4+8=13,X=1101时,表示+1-2+4+8=11,以此类推可以得到任意奇数,偶数同理)
所以可以从2k往前推,当前值比n大就去-,小就取+。
1 // 2 //by coolxxx 3 // 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<memory.h> 9 #include<time.h> 10 #include<stdio.h> 11 #include<stdlib.h> 12 #include<string.h> 13 #include<stdbool.h> 14 #include<math.h> 15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) ((a)*(a)) 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 21 #define eps 1e-8 22 #define J 10 23 #define MAX 0x7f7f7f7f 24 #define PI 3.1415926535897 25 #define N 77 26 using namespace std; 27 int cas,cass; 28 long long n,m,lll,ans; 29 long long e[N]; 30 void print(int top,int x) 31 { 32 if(top==0) 33 { 34 if(x<n)puts("1 +"); 35 else puts("1 -"); 36 return; 37 } 38 if(x>n) 39 { 40 print(top-1,x-e[top]); 41 printf("%lld -\n",e[top]); 42 } 43 else 44 { 45 print(top-1,x+e[top]); 46 printf("%lld +\n",e[top]); 47 } 48 } 49 int main() 50 { 51 #ifndef ONLINE_JUDGE 52 // freopen("1.txt","r",stdin); 53 // freopen("2.txt","w",stdout); 54 #endif 55 int i,j,k; 56 // while(~scanf("%s",s1)) 57 // while(~scanf("%d",&n)) 58 for(e[0]=1,i=1;i<=61;i++) 59 e[i]=e[i-1]<<1; 60 for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 61 { 62 printf("Case #%d:\n",cass); 63 scanf("%lld%lld",&n,&m); 64 m--; 65 if(n&1) 66 { 67 print(m-1,e[m]); 68 printf("%lld +\n",e[m]); 69 } 70 else 71 { 72 print(m-1,e[m]+1); 73 printf("%lld +\n",e[m]+1); 74 } 75 } 76 return 0; 77 } 78 79 /* 80 // 81 82 // 83 */