Amazon Interview Question
Country: India
find rank of a and rank of b; find difference in ranks.
where rank for 10101 can be found as [c(5,1)+c(5,2)+C(5,3)+C(5,5)]-[C(3,0)+C(3,1)+C(3,3)]-[C(1,1)],
basically what we looking is total how many can be found with 5 digits subtract numbers which are greater than the current.
what about the first number of the range?? how you will identify the minimum of the range and make sure you dont go beyond that.
u can use first number-1;
we have to find rank(b)-rank(a-1) where b>a;
To find rank of a unmber, lets say it has n bits(last non-zero bit is n-1th), then get count of fib numbers having n or less bits, then subtract for each 0 bit assume it to be one and compute how many fib numbers can be found fixing the preix part and changinh the least bits.
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cstring>
using namespace std;
int fab[100];
int dp[70][70][2];
long long right;
void check()
{
int a = 0;
int b = 1;
int c = 0;
fab[0] = 1;
fab[1] = 1;
while ( c <= 64 ) {
c = a + b;
fab[c] = 1;
a = b;
b = c;
}
}
long long solve( int p , int c , int eq )
{
if ( p == -1 ) {
if( fab[c] == 1 )
return 1;
else
return 0;
}
if( dp[p][c][eq] != -1 )
return dp[p][c][eq];
extern long long right;
long long ans = 0;
if( eq ) {
if( ( 1<<p ) & right ) {
ans = ans + solve( p - 1 , c + 1 , 1 );
ans = ans + solve( p - 1 , c , 0 );
} else {
ans = ans + solve( p - 1 , c , 1 );
}
} else {
ans = ans + solve( p - 1 , c + 1 , 0 );
ans = ans + solve( p - 1 , c , 0 );
}
dp[p][c][eq] = ans;
return ans;
}
int main()
{
int n;
int t;
cin >> t;
memset( fab , 0 , sizeof( fab ) );
memset( dp , -1 , sizeof( dp ) );
check();
long long a , b , ans;
extern long long right;
while( t )
{
t--;
memset( dp , -1 , sizeof( dp ) );
fflush( stdin );
cin >> a >> b;
right = b;
ans = solve( 30, 0 , 1 );
if( a > 0 )
right = a - 1;
else
right = 0;
memset( dp , -1 , sizeof( dp ) );
right = a - 1;
ans = ans - solve( 30 , 0 , 1 );
cout << ans << "\n";
}
cin >> n;
return 0;
}
void main()
{
int no;
printf("Enter the no.");
scanf("%d",&no);
for(int i=no; i<no+64;i++)
{
int r = fibonnaci(i);
if(r==1)
{
do{
i=i%2;
if(i==1)
p++;
i=i/2;
}while(i>0);
}else
printf("no. is not in fibonnaci series");
}
int fibonnaci(int w)
{ int a=0,b=1,c;
for(int i=0; i<w;i++)
{
if(c==w)
return 1;
else
{
c=a+b;
a=b;
b=c;
}
}
}
i think the best way to achieve it is.
1-First create a fib array which contains all fibonacci numbers between 0 and 64, there will be at most 11.
2-then count no. of set bits in A and B in O(1) time.
3-after that do a binary search on fib array to find no. of fibonacci numbers in b/w with O(1).
- anonymous July 07, 2012