Divide and Conquer -Binary Search

uva 679 - Dropping Balls

有K个球从一完整二元树(fully binary tree, FBT)的树根(root)一个一个往下掉。当这个球遇到非终端节点时,可能往左子树跑,也可能往右子树跑,如此直到这颗球到达终端节点(也就是树叶)为止。至于在非终端节点时球该往左或往右的决定乃是由2个值true, false 来控制的。如果这非终端节点的现在的值为false,则球来的时候会往左子树走,但是这个值会变为true。如果这非终端节点的现在的值为true,则球来的时候会往右子树走,但是这个值会变为false。请注意:一开始时所有非终端节点的值均为false。另外,在完整二元树中所有的节点被依序编号,从上(深度= 1)到下,由左到右。请参考下图。

举例来说,上面的图为深度为4的完整二元树。第一颗球往下掉会经过节点1、2、4最后落在节点8中。第二颗球往下掉则会经过节点1、3、6最后落在节点12中。第三颗球往下掉会经过节点1、2、5最后落在节点10中。

给你完整二元树的深度D以及落下的第I个球,请你写一个程式算出第I个球落在终端节点的编号。

Input :

输入的第一列有一个整数,代表以下有几组测试资料。

每组测试资料一列有2个整数D,I(2 <= D <= 20, 1 <= I <= 524288)。

Output :

对每组测试资料输出一列,第I个球落在终端节点的编号。

Sample Input :

 
5
4 2
3 4
10 1
2 2
8 128

 

Sample Output :

12
7
512
3
255

 1 #include<iostream>
2 #include<cstdio>
3 #include<vector>
4 #include<string.h>
5 #include<cmath>
6 #include<queue>
7 #include<set>
8 #include<cstdlib>
9 #include<algorithm>
10 #include<functional>
11 #include<map>
12 #include <iomanip>
13 #include <bitset>
14 #include<iterator>
15 using namespace std;
16 #define LL long long
17 const int MAX = 200010;
18 const int INF=100000000;
19 const double eps= 1e-10;
20 int f[30],sum[30];
21 int main(){
22 int T,n,m;
23 f[0]=0; for(int i=1;i<=30;i++) f[i]=(1<<(i-1));
24 sum[0]=0; for(int i=1;i<=30;i++) sum[i]=(1<<(i-1))-1;
25 scanf("%d",&T);
26 while(T--){
27 scanf("%d%d",&m,&n);
28 n--; m--;
29 int ans=1;
30 for(int i=1;i<=m;i++){
31 int x=ans-sum[i];
32 if(f[i]&n) {
33 ans+= (x-1)*2+(f[i]-x) + 2;
34 }else{
35 ans+= (x-1)*2+(f[i]-x)+1;
36 }
37 }
38 printf("%d\n",ans);
39 }
40 }


uva 10742 - The New Rule in Euphomia

注意处理好二分时上下界问题,及lower_bound与upper_bound

 1 #include<iostream>
2 #include<cstdio>
3 #include<vector>
4 #include<string.h>
5 #include<cmath>
6 #include<queue>
7 #include<set>
8 #include<cstdlib>
9 #include<algorithm>
10 #include<functional>
11 #include<map>
12 #include <iomanip>
13 #include <bitset>
14 #include<iterator>
15 using namespace std;
16 #define LL long long
17 const int MAX = 1000100;
18 const int INF=100000000;
19 const double eps= 1e-10;
20 int num_prime,prime[MAX];
21 bool vis[MAX];
22 void get_prime() {
23 num_prime=0;
24 memset(vis,true,sizeof(vis));
25 prime[num_prime++]=2;
26 for(int i=3;i<MAX;i+=2){
27 if(vis[i]){
28 prime[num_prime++]=i;
29 for(int j=i+i;j<MAX;j+=i) vis[j]=false;
30 }
31 }
32 }
33 int main(){
34 get_prime();
35 int n,T=1;
36 while(scanf("%d",&n)&&n){
37 int ans=0;
38 for(int i=0;prime[i]<n;i++){
39 int *id;
40 id=upper_bound(prime,prime+num_prime,n-prime[i]);
41 id--;
42 if(id<=prime+i) break;
43 ans+=id-(prime+i);
44 }
45 printf("Case %d: %d\n",T++,ans);
46 }
47 }



posted @ 2012-03-14 20:46  HaoHua_Lee  阅读(246)  评论(0编辑  收藏  举报