📜  生成与其右旋除数相等的数字

📅  最后修改于: 2021-04-26 11:01:27             🧑  作者: Mango

给定一个数字m,找到所有具有m个数字并且都是其右旋除数的数字。数字N的右旋转是将N的数字向右旋转一位并将最不重要的数字环绕起来使其变为最重要的数字的结果。例如,右转4356为6435。
例子:

Input : 2
Output :
11
22
33
44
55
66
77
88
99

Input : 6
Output:
102564
111111
128205
142857
153846
179487
205128
222222
230769
333333
444444
555555
666666
777777
888888
999999

128205 satisfies the condition as 128205 * 4 = 512820.



蛮力法
最简单的方法是遍历所有大于或等于10 m-1且小于10 m的数字,并检查它们是否满足要求的条件。我们可以在固定时间内对其进行检查,因此整个过程的时间复杂度为O(10 m ),这仅适用于较小的m值。
下面是上述方法的实现:

C++
// C++ program to Generating numbers that
// are divisor of their right-rotations
 
#include 
using namespace std;
 
   
// Function to check if N is a
// divisor of its right-rotation
 
bool rightRotationDivisor(int N)
{
    int lastDigit = N % 10;
    int rightRotation = (lastDigit * pow(10 ,int(log10(N))))
                    + floor(N / 10);
    return (rightRotation % N == 0);
}
   
// Function to generate m-digit
// numbers which are divisor of
// their right-rotation
void generateNumbers(int m)
{
    for (int i=pow(10,(m - 1));i


Java
// Java program to Generating numbers that 
// are divisor of their right-rotations  
 
public class GFG {
     
    // Function to check if N is a 
    // divisor of its right-rotation
    static boolean rightRotationDivisor(int N)
    {
        int lastDigit = N % 10;
        int rightRotation = (int)(lastDigit * Math.pow(10 ,(int)(Math.log10(N))) 
                        + Math.floor(N / 10)); 
        return (rightRotation % N == 0);
    }
         
    // Function to generate m-digit 
    // numbers which are divisor of 
    // their right-rotation 
    static void generateNumbers(int m)
    {
        for (int i= (int)Math.pow(10,(m - 1)); i < Math.pow(10 , m);i++) 
            if (rightRotationDivisor(i))
                System.out.println(i);
     }
 
     
    // Driver code
    public static void main(String args[])
    {
        int m = 3;
        generateNumbers(m);
     
    }
    // This Code is contributed by ANKITRAI1
}


Python3
# Python program to Generating numbers that are
# divisor of their right-rotations
 
from math import log10
 
# Function to check if N is a
# divisor of its right-rotation
def rightRotationDivisor(N):
    lastDigit = N % 10
    rightRotation = (lastDigit * 10 ** int(log10(N))
                    + N // 10)
    return rightRotation % N == 0
 
# Function to generate m-digit
# numbers which are divisor of
# their right-rotation
def generateNumbers(m):
    for i in range(10 ** (m - 1), 10 ** m):
        if rightRotationDivisor(i):
            print(i)
 
# Driver code
m = 3
generateNumbers(m)


C#
// C# program to Generating numbers that
// are divisor of their right-rotations 
 
using System;
public class GFG{
 
    // Function to check if N is a
    // divisor of its right-rotation
    static bool rightRotationDivisor(int N)
    {
        int lastDigit = N % 10;
        int rightRotation = (int)(lastDigit * Math.Pow(10 ,(int)(Math.Log10(N)))
                        + Math.Floor((double)N/10));
        return (rightRotation % N == 0);
    }
         
    // Function to generate m-digit
    // numbers which are divisor of
    // their right-rotation
    static void generateNumbers(int m)
    {
        for (int i= (int)Math.Pow(10,(m - 1)); i < Math.Pow(10 , m);i++)
            if (rightRotationDivisor(i))
                Console.WriteLine(i);
    }
 
     
    // Driver code
    public static void Main()
    {
        int m = 3;
        generateNumbers(m);
     
    }
}
 
// This code is contributed by 29AjayKumar


PHP


C++
// C++ program to Generating
// numbers that are divisor
// of their right-rotations
#include 
using namespace std;
 
// Function to generate m-digit
// numbers which are divisor of
// their right-rotation
void generateNumbers(int m)
{
  vector numbers;
  int k_max, x;
 
  for (int y = 0; y < 10; y++)
  {
    k_max = (int)(pow(10, m - 2) *
                     (10 * y + 1)) /
            (int)(pow(10, m - 1) + y);
 
    for (int k = 1; k <= k_max; k++)
    {
      x = (int)(y * (pow(10, m - 1) - k)) /
                        (10 * k - 1);
 
      if ((int)(y * (pow(10, m - 1) - k)) %
                        (10 * k - 1) == 0)
        numbers.push_back(10 * x + y);
    }
  }
 
  sort(numbers.begin(), numbers.end());
  for (int i = 0; i < numbers.size(); i++)
    cout << (numbers[i]) << endl;
}
 
// Driver code
int main()
{
  int m = 3;
  generateNumbers(m);
}
 
// This code is contributed by Chitranayal


Java
// Java program to Generating numbers that
// are divisor of their right-rotations
import java.util.*;
import java.io.*;
 
class GFG
{
 
    // Function to generate m-digit
    // numbers which are divisor of
    // their right-rotation
    static void generateNumbers(int m)
    {
            ArrayList numbers = new ArrayList<>();
            int k_max, x;
 
            for (int y = 0; y < 10; y++)
            {
 
                k_max = (int)(Math.pow(10,m-2) * (10 * y + 1)) /
                                (int)(Math.pow(10, m-1) + y);
 
                for (int k = 1; k <= k_max; k++)
                {
                        x = (int)(y*(Math.pow(10,m-1)-k)) / (10 * k -1);
 
                        if ((int)(y*(Math.pow(10,m-1)-k)) % (10 * k -1) == 0)
                            numbers.add(10 * x + y);
                }
 
            }
 
            Collections.sort(numbers);
            for (int i = 0; i < numbers.size(); i++)
                System.out.println(numbers.get(i));
    }
 
    // Driver code
    public static void main(String args[])
    {
            int m = 3;
            generateNumbers(m);
    }
}
 
// This code is contributed by rachana soma


Python 3
# Python program to Generating numbers that
# are divisor of their right-rotations
from math import log10
 
# Function to generate m-digit
# numbers which are divisor of
# their right-rotation
def generateNumbers(m):
    numbers = []
     
    for y in range(1, 10):
        k_max = ((10 ** (m - 2) *
                (10 * y + 1)) //
                (10 ** (m - 1) + y))
         
        for k in range(1, k_max + 1):
            x = ((y * (10 ** (m - 1) - k))
                // (10 * k - 1))
             
            if ((y * (10 ** (m - 1) - k))
                % (10 * k - 1) == 0):
                numbers.append(10 * x + y)
     
    for n in sorted(numbers):
        print(n)
 
# Driver code
m = 3
generateNumbers(m)


C#
// C# program to Generating numbers that
// are divisor of their right-rotations
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Function to generate m-digit
// numbers which are divisor of
// their right-rotation
static void generateNumbers(int m)
{
    List numbers = new List();
    int k_max, x;
 
    for (int y = 0; y < 10; y++)
    {
 
        k_max = (int)(Math.Pow(10, m - 2) * (10 * y + 1)) /
                (int)(Math.Pow(10, m - 1) + y);
 
        for (int k = 1; k <= k_max; k++)
        {
            x = (int)(y * (Math.Pow(10, m - 1) - k)) /
                                   (10 * k - 1);
 
            if ((int)(y * (Math.Pow(10, m - 1) - k)) %
                                   (10 * k - 1) == 0)
                numbers.Add(10 * x + y);
        }
    }
 
    numbers.Sort();
    for (int i = 0; i < numbers.Count; i++)
        Console.WriteLine(numbers[i]);
}
 
// Driver code
public static void Main(String []args)
{
    int m = 3;
    generateNumbers(m);
}
}
 
// This code is contributed by PrinciRaj1992


输出:
111
222
333
444
555
666
777
888
999



时间复杂度:O(10 m )
高效的方法
d m d m-1 ..d 3 d 2 d 1是我们要生成的数字的一般形式。取x = d m d m-1 ..d 3 d 2y = d 1 。我们要满足的条件是y * 10 m – 1 + x = k *(10x + y) ,其中k是一个正整数。重新排列这些项,我们得到x =(y *(10 m-1 -k))/(10k-1) 。因此,如果我们固定y和k的值,我们可以得到x的值,使得10x + y是我们需要生成的数字。
y的值可以在1到9之间;请注意,我们将没有y = 0的情况,因为这将使右旋转y * 10 m – 1 + x具有m – 1个数字,并且永远不会满足所需的条件。
我们要求x的位数为m – 1,即

10^{m - 2} \leq x < 10^{m - 1} \\ \Rightarrow 10^{m - 2} \leq y\frac{10^{m - 1} - k}{10k - 1} < 10^{m - 1} \\ \Rightarrow 10^{m - 1}k - 10^{m - 2} \leq y(10^{m - 1} - k) < 10^{m}k - 10^{m - 1} \\ \Rightarrow \frac{10^{m - 1}(y + 1)}{10^m + y} < k \leq \frac{10^{m - 2}(10y + 1)}{10^{m - 1} + y}

我们可以观察到下界始终小于1,因此我们可以将其保持为1,因为k必须为正整数。
我们可以使用这些结果来获得高效的解决方案,该解决方案以恒定的时间复杂度运行,即O(1)。需要注意的重要一点是,获得的数字可能不是排序形式的,因此,如果我们希望以排序的方式获得数字,则需要存储它们并对其进行显式排序。
下面是上述方法的实现:

C++

// C++ program to Generating
// numbers that are divisor
// of their right-rotations
#include 
using namespace std;
 
// Function to generate m-digit
// numbers which are divisor of
// their right-rotation
void generateNumbers(int m)
{
  vector numbers;
  int k_max, x;
 
  for (int y = 0; y < 10; y++)
  {
    k_max = (int)(pow(10, m - 2) *
                     (10 * y + 1)) /
            (int)(pow(10, m - 1) + y);
 
    for (int k = 1; k <= k_max; k++)
    {
      x = (int)(y * (pow(10, m - 1) - k)) /
                        (10 * k - 1);
 
      if ((int)(y * (pow(10, m - 1) - k)) %
                        (10 * k - 1) == 0)
        numbers.push_back(10 * x + y);
    }
  }
 
  sort(numbers.begin(), numbers.end());
  for (int i = 0; i < numbers.size(); i++)
    cout << (numbers[i]) << endl;
}
 
// Driver code
int main()
{
  int m = 3;
  generateNumbers(m);
}
 
// This code is contributed by Chitranayal

Java

// Java program to Generating numbers that
// are divisor of their right-rotations
import java.util.*;
import java.io.*;
 
class GFG
{
 
    // Function to generate m-digit
    // numbers which are divisor of
    // their right-rotation
    static void generateNumbers(int m)
    {
            ArrayList numbers = new ArrayList<>();
            int k_max, x;
 
            for (int y = 0; y < 10; y++)
            {
 
                k_max = (int)(Math.pow(10,m-2) * (10 * y + 1)) /
                                (int)(Math.pow(10, m-1) + y);
 
                for (int k = 1; k <= k_max; k++)
                {
                        x = (int)(y*(Math.pow(10,m-1)-k)) / (10 * k -1);
 
                        if ((int)(y*(Math.pow(10,m-1)-k)) % (10 * k -1) == 0)
                            numbers.add(10 * x + y);
                }
 
            }
 
            Collections.sort(numbers);
            for (int i = 0; i < numbers.size(); i++)
                System.out.println(numbers.get(i));
    }
 
    // Driver code
    public static void main(String args[])
    {
            int m = 3;
            generateNumbers(m);
    }
}
 
// This code is contributed by rachana soma

的Python 3

# Python program to Generating numbers that
# are divisor of their right-rotations
from math import log10
 
# Function to generate m-digit
# numbers which are divisor of
# their right-rotation
def generateNumbers(m):
    numbers = []
     
    for y in range(1, 10):
        k_max = ((10 ** (m - 2) *
                (10 * y + 1)) //
                (10 ** (m - 1) + y))
         
        for k in range(1, k_max + 1):
            x = ((y * (10 ** (m - 1) - k))
                // (10 * k - 1))
             
            if ((y * (10 ** (m - 1) - k))
                % (10 * k - 1) == 0):
                numbers.append(10 * x + y)
     
    for n in sorted(numbers):
        print(n)
 
# Driver code
m = 3
generateNumbers(m)

C#

// C# program to Generating numbers that
// are divisor of their right-rotations
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Function to generate m-digit
// numbers which are divisor of
// their right-rotation
static void generateNumbers(int m)
{
    List numbers = new List();
    int k_max, x;
 
    for (int y = 0; y < 10; y++)
    {
 
        k_max = (int)(Math.Pow(10, m - 2) * (10 * y + 1)) /
                (int)(Math.Pow(10, m - 1) + y);
 
        for (int k = 1; k <= k_max; k++)
        {
            x = (int)(y * (Math.Pow(10, m - 1) - k)) /
                                   (10 * k - 1);
 
            if ((int)(y * (Math.Pow(10, m - 1) - k)) %
                                   (10 * k - 1) == 0)
                numbers.Add(10 * x + y);
        }
    }
 
    numbers.Sort();
    for (int i = 0; i < numbers.Count; i++)
        Console.WriteLine(numbers[i]);
}
 
// Driver code
public static void Main(String []args)
{
    int m = 3;
    generateNumbers(m);
}
}
 
// This code is contributed by PrinciRaj1992
输出:
111
222
333
444
555
666
777
888
999



时间复杂度:O(1)