八角星数


在数学中,八角星数是一种基于八角星的图形数,其形式为 n(2n2 − 1)。

是完全平方数的八角星数为 19653449

问题陈述

给定一个数字 n,检查它是否为八角星数。八角星数的序列为 0、1、14、51、124、245、426、679、1016、1449、1990。

示例1

输入

x = 14

输出

Yes

解释

$$\mathrm{对于 n = 2,表达式 n\lgroup 2n^2 – 1\rgroup 为 14}$$

示例2

输入

n = 22

输出

No

解释

$$\mathrm{不存在 n 使得 n(2n^2 – 1) 等于 22}$$

解决方案

有两种可能的解决方案。

方法 1

解决此问题的一种简单方法是从 n 等于 0 开始,找到 n(2n2 – 1) 的值,然后将其与给定数字(将其视为 x)进行比较。我们将继续增加 n 并重新计算 n(2n2 – 1),直到它等于 x,这将意味着 x 是八角星数。如果值变得大于 x,我们将停止,这意味着 x 不是八角星数。

伪代码

Start
while n*(2*n*n - 1) is less than x
	n = n + 1
if n*(2*n*n - 1) is equal to x
	then return yes
else return false
End

示例

下面是一个 C++ 程序,用于使用上述方法检查给定数字是否为八角星数。

#include <iostream>
using namespace std;
// Function to check the input number
int checkStellaOctangula(int x){
   // Initiating n from 0
   int n = 0;
   // Calculating n*(2*n*n - 1) for each n
   // and incrementing n if it is less than x
   while(n*(2*n*n - 1)<x){
      n++;
   }
   // checking if the value of an expression is equal to x
   // if it's equal, return true
   if(n*(2*n*n - 1)==x){
      return true;
   }
   // otherwise return false
   return false;
}
int main(){
   int x = 51;
   if (checkStellaOctangula(x)){  
      cout << "Yes";
   }
   else{
      cout << "No";
   }
   return 0;
}

输出

对于输入 x = 52,上述 C++ 程序将产生以下输出:

Yes

此方法的时间复杂度可能达到 O(x),因为上限为 x。

此方法的空间复杂度为 O(1),因为它不使用任何额外的空间。

方法 2

检查数字是否为八角星数的更有效方法是使用无界二分搜索。

在这种方法中,我们从 n = 1 开始,每次将 i 的值加倍时都计算 n(2n2 – 1) 的值。我们将这样做,直到表达式 n(2n2 – 1) 的值小于 x。

之后,我们将检查表达式的值是否等于 x。如果等于 x,则返回真,否则我们调用二分搜索。在此调用中,我们将 x 与表达式 n(2n2 – 1) 在 n/2 到 n 范围内的值进行比较,如果它们相等则返回真,否则返回假。

伪代码

Start
while n*(2*n*n - 1) is less than x
	n = n * 2
if n*(2*n*n - 1) is equal to x
	then return yes
else 
	Repeat until low>=high
	mid=(low+high)/2 
	If n*(2*n*n - 1) < x, 
		low=mid+1 
	Else If n*(2*n*n - 1) > x 
		high=mid-1
	else 
		return true
End

示例

下面是一个 C++ 程序,用于使用上述方法检查给定数字是否为八角星数。

#include <bits/stdc++.h>
using namespace std;
// Function to calculate value of n*(2*n*n - 1)
int calculateExp(int n) {
   return n*(2*n*n - 1);
}
// Using binary search to search for a value of n for which
// expression has value equal to x
// where n lies in the interval (low to high)
// low is n/2 and high is n
bool binarySearch(int low, int high, int x){
   while (low <= high) {
      int mid = (low + high) / 2;
      if (calculateExp(mid) < x){
         low = mid + 1;
      }
      else if (calculateExp(mid) > x){
         high = mid - 1;
      }
     else{
         return true;
      }
   }
   return false;
}
// Function to check the input number
bool checkStellaOctangula(int x){
   // Edge case
   if (x == 0)
   return true;
   // Starting from n = 1 and doubling it
   // while the value of expression is less than x
   int n = 1;
   while (calculateExp(n) < x){
      n = n*2;
   }
   // If the expression is equal to x
   // return true
   if (calculateExp(n) == x){
      return true;
   }
   // Otherwise call binary search
   // range for the search decided by
   // finding value of expression for n
   // in range n/2 to n
 return binarySearch(n/2, n, x);
}

int main(){
   int x = 51;
   if (checkStellaOctangula(x)){ 
      cout << "Yes";
   }
   else{
      cout << "No";
   }
   return 0;
}

输出

对于输入 x = 51,上述 C++ 程序将产生以下输出:

Yes

时间复杂度为 O(log n),因为我们每次迭代都将 n 的值加倍。

此方法的空间复杂度为 O(1),因为它不使用任何额外的空间。

结论

我们讨论了两种方法。在第一种方法中,我们线性地递增 n 并计算每个值的 n*(2*n*n - 1),并将其与 x 进行比较。这种方法非常缓慢且效率低下。在第二种方法中,我们将 n 的值加倍,然后计算 n*(2*n*n - 1) 并将其与 x 进行比较,这是一种更快、更有效的方法。

更新于: 2023年8月24日

111 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告