先决条件:二进制搜索
给定两个正整数N和K ,任务是计算满足以下条件的所有数字:
如果数字是num ,
- num≤N 。
- abs(num – count)≥K ,其中count是直到num的斐波那契数的计数。
例子:
Input: N = 10, K = 3
Output: 2
Explanation:
9 and 10 are the valid numbers which satisfy the given conditions.
For 9, the difference between 9 and fibonacci numbers upto 9 (0, 1, 2, 3, 5, 8) is i.e. 9 – 6 = 3.
For 10, the difference between 9 and fibonacci numbers upto 10 (0, 1, 2, 3, 5, 8) is i.e. 10 – 6 = 4.
Input: N = 30, K = 7
Output: 11
观察:仔细观察,该函数是斐波纳契数的数目与该数目之差的函数,对于特定K而言,是单调递增的函数。同样,如果数字X是有效数字,则X +1也是有效数字。
证明:
- Let the function Ci denotes the count of fibonacci numbers upto number i.
- Now, for the number X + 1 the difference is X + 1 – CX + 1 which is greater than or equal to the difference X – CX for the number X, i.e. (X + 1 – CX + 1) ≥ (X – CX).
- Thus, if (X – CX) ≥ S, then (X + 1 – CX + 1) ≥ S.
方法:因此,从以上观察可知,其思想是使用散列来预先计算和存储Fibonacci节点直到最大值,并使用前缀和数组概念创建一个前缀数组,其中每个索引存储的Fibonacci数字的数量小于’我要使检查变得容易和高效(在O(1)时间内)。
现在,我们可以使用二进制搜索来找到最小有效数字X ,因为范围[ X , N ]中的所有数字都是有效的。因此,答案将是N – X + 1 。
下面是上述方法的实现:
C/C++
// C++ program to find the count
// of numbers whose difference with
// Fibonacci count upto them is atleast K
#include
using namespace std;
const int MAX = 1000005;
// fibUpto[i] denotes the count of
// fibonacci numbers upto i
int fibUpto[MAX + 1];
// Function to compute all the Fibonacci
// numbers and update fibUpto array
void compute(int sz)
{
bool isFib[sz + 1];
memset(isFib, false, sizeof(isFib));
// Store the first two Fibonacci numbers
int prev = 0, curr = 1;
isFib[prev] = isFib[curr] = true;
// Compute the Fibonacci numbers
// and store them in isFib array
while (curr <= sz) {
int temp = curr + prev;
isFib[temp] = true;
prev = curr;
curr = temp;
}
// Compute fibUpto array
fibUpto[0] = 1;
for (int i = 1; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1];
if (isFib[i])
fibUpto[i]++;
}
}
// Function to return the count
// of valid numbers
int countOfNumbers(int N, int K)
{
// Compute fibUpto array
compute(N);
// Binary search to find the minimum
// number that follows the condition
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
// Check if the number is
// valid, try to reduce it
if (mid - fibUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
// Ans is the minimum valid number
return (ans ? N - ans + 1 : 0);
}
// Driver Code
int main()
{
int N = 10, K = 3;
cout << countOfNumbers(N, K);
}
Java
// Java program to find the count
// of numbers whose difference with
// Fibonacci count upto them is atleast K
import java.util.*;
class GFG{
static int MAX = 1000005;
// fibUpto[i] denotes the count of
// fibonacci numbers upto i
static int []fibUpto = new int[MAX + 1];
// Function to compute all the Fibonacci
// numbers and update fibUpto array
static void compute(int sz)
{
boolean []isFib = new boolean[sz + 1];
// Store the first two Fibonacci numbers
int prev = 0, curr = 1;
isFib[prev] = isFib[curr] = true;
// Compute the Fibonacci numbers
// and store them in isFib array
while (curr <= sz) {
int temp = curr + prev;
if(temp <= sz)
isFib[temp] = true;
prev = curr;
curr = temp;
}
// Compute fibUpto array
fibUpto[0] = 1;
for (int i = 1; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1];
if (isFib[i])
fibUpto[i]++;
}
}
// Function to return the count
// of valid numbers
static int countOfNumbers(int N, int K)
{
// Compute fibUpto array
compute(N);
// Binary search to find the minimum
// number that follows the condition
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
// Check if the number is
// valid, try to reduce it
if (mid - fibUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
// Ans is the minimum valid number
return (ans>0 ? N - ans + 1 : 0);
}
// Driver Code
public static void main(String[] args)
{
int N = 10, K = 3;
System.out.print(countOfNumbers(N, K));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python 3 program to find the count
# of numbers whose difference with
# Fibonacci count upto them is atleast K
MAX = 1000005
# fibUpto[i] denotes the count of
# fibonacci numbers upto i
fibUpto = [0]*(MAX + 1)
# Function to compute all the Fibonacci
# numbers and update fibUpto array
def compute(sz):
isFib = [False]*(sz + 1)
# Store the first two Fibonacci numbers
prev = 0
curr = 1
isFib[prev] = True
isFib[curr] = True
# Compute the Fibonacci numbers
# and store them in isFib array
while (curr <=sz):
temp = curr + prev
if(temp<=sz):
isFib[temp] = True
prev = curr
curr = temp
# Compute fibUpto array
fibUpto[0] = 1
for i in range( 1,sz+1):
fibUpto[i] = fibUpto[i - 1]
if (isFib[i]):
fibUpto[i]+=1
# Function to return the count
# of valid numbers
def countOfNumbers(N, K):
# Compute fibUpto array
compute(N)
# Binary search to find the minimum
# number that follows the condition
low , high, ans = 1, N, 0
while (low <= high):
mid = (low + high) >> 1
# Check if the number is
# valid, try to reduce it
if (mid - fibUpto[mid] >= K):
ans = mid
high = mid - 1
else:
low = mid + 1
# Ans is the minimum valid number
if(ans):
return (N - ans + 1)
return 0
# Driver Code
if __name__ == "__main__":
N = 10
K = 3
print(countOfNumbers(N, K))
# This code is contributed by chitranayal
C#
// C# program to find the count
// of numbers whose difference with
// Fibonacci count upto them is atleast K
using System;
class GFG{
static int MAX = 1000005;
// fibUpto[i] denotes the count of
// fibonacci numbers upto i
static int []fibUpto = new int[MAX + 1];
// Function to compute all the Fibonacci
// numbers and update fibUpto array
static void compute(int sz)
{
bool []isFib = new bool[sz + 1];
// Store the first two Fibonacci numbers
int prev = 0, curr = 1;
isFib[prev] = isFib[curr] = true;
// Compute the Fibonacci numbers
// and store them in isFib array
while (curr <= sz) {
int temp = curr + prev;
if(temp <= sz)
isFib[temp] = true;
prev = curr;
curr = temp;
}
// Compute fibUpto array
fibUpto[0] = 1;
for (int i = 1; i <= sz; i++) {
fibUpto[i] = fibUpto[i - 1];
if (isFib[i])
fibUpto[i]++;
}
}
// Function to return the count
// of valid numbers
static int countOfNumbers(int N, int K)
{
// Compute fibUpto array
compute(N);
// Binary search to find the minimum
// number that follows the condition
int low = 1, high = N, ans = 0;
while (low <= high) {
int mid = (low + high) >> 1;
// Check if the number is
// valid, try to reduce it
if (mid - fibUpto[mid] >= K) {
ans = mid;
high = mid - 1;
}
else
low = mid + 1;
}
// Ans is the minimum valid number
return (ans>0 ? N - ans + 1 : 0);
}
// Driver Code
public static void Main()
{
int N = 10, K = 3;
Console.WriteLine(countOfNumbers(N, K));
}
}
// This code is contributed by Mohitkumar29
2