Huawei Machine Test-find ugly number (optimized to 20ms)

Source: Internet
Author: User

Title Description:

The numbers that contain only the factors 2, 3, and 5 are called ugly Numbers (Ugly number). For example, 6, 8 are ugly numbers, but 14 is not, because it contains factor 7.
We used to think of 1 as the first ugly number. Find the nth ugly number in order from small to large.

Input:

The input includes an integer N (1<=n<=1500).

Output:

There may be multiple sets of test data, for each set of data,
Outputs the nth number of ugly characters.

Sample input:
3
Sample output:
3

so-called a number m is another number n , which means n can be divisible by m , which is n% m = = 0 . According to the definition of ugly number, the number of ugly can only be 2 , 3 and 5 is divisible. That is, if a number is divisible by 2 , we divide it consecutively by 2 If it can be divisible by 3 , it is divided by 3 ; if it can be 5 is divisible by the continuous 5 . If the last we get is 1 , then this number is the number of ugly, otherwise not.

Based on the previous analysis, we can write the following function to determine whether a number is an ugly number:

BOOL isugly (int number) {while (number% 2 = = 0) number        /= 2;    while (number% 3 = = 0) number        /= 3;    while (number% 5 = = 0) number        /= 5;    return (number = = 1)? True:false;}


Next, we only need to determine in sequence whether each integer is an ugly number, that is:

int getuglynumber (int index) {if (index <= 0)        return 0;    int number = 0;    int uglyfound = 0;    while (Uglyfound < index)    {++number;        if (isugly (number)) ++uglyfound;} return number;}

We only need to pass the parameter in the function Getuglynumber, we can get the first number of ugly. The algorithm is very intuitive, the code is very concise, but the biggest problem we need to calculate each integer. Even if a number is not an ugly number, we still need to do the remainder and division operation. Therefore, the time efficiency of the algorithm is not very high.

Next we'll take a different approach to the problem, trying to calculate only the number of ugly, not the whole number of non-ugly numbers to spend time on. According to the definition of ugliness, the ugly number should be the result of another ugly number multiplied by 2,3 , or 5 (except1 ). So we can create an array in which the number is the number of ugly numbers in good order. Each of the ugly numbers in the front is multiplied by 2,3 , or 5 .

The key to this idea is how to make sure that the number of ugly numbers inside the array is orderly. We assume that there are already a number of ugly numbers in the array, and that there are arrays in the sequence. We're doing the biggest ugly number we've got.M。 Now we're going to generate the next ugly number, which is definitely the number of ugly times before.2、3Or5The result. We first consider multiplying the number of ugly2。 multiplied by2, you can get a number of results less than or equal toMOf Since we are generated in order, less than or equal toMDefinitely already in the array, we don't need to think about it again; we'll get a few more thanMResults, but we only need the first one greater thanMresult, because we hope that the ugly number is generated from small to large order, other larger results we will say later. We multiply the first one we get.2After greater thanMThe result is recorded asM2。 And we multiply every ugly number we've got.3And5, can get the first one greater thanMThe resultsM3AndM5。 Then the next ugly number should beM2、M3AndM5The smallest of the three numbers.

In front of our analysis, it is mentioned that each of the existing ugly number is multiplied by 2,3 and 5, in fact, is not necessary, because the existing number of ugly is in order to exist in the array. For times of 2 , there must be an ugly number T2, every ugly number before it multiplied by 2 results will be less than the maximum number of ugly, after which every ugly number multiplied by 2 results will be too large. We just need to write down the location of this ugly number and update the T2every time we generate a new number of ugly numbers. For Times 3 and 5 , the same T3 and T5exist.

With these analyses, it is not difficult to write the following code:

int puglynumbers[1501];int getuglynumber (int index) {if (index <= 0)        return 0;    Puglynumbers[0] = 1;    int nextuglyindex = 1;    int index2 = 0;    int index3 = 0;    int index5 = 0;    while (Nextuglyindex < index) {int min = min (puglynumbers[index2] * 2, PUGLYNUMBERS[INDEX3] * 3, PUGLYNUMBERS[INDEX5] * 5 );        Puglynumbers[nextuglyindex] = Min;while (puglynumbers[index2] * 2 <= puglynumbers[nextuglyindex]) ++index2;        while (PUGLYNUMBERS[INDEX3] * 3 <= puglynumbers[nextuglyindex])            ++index3;        while (PUGLYNUMBERS[INDEX5] * 5 <= Puglynumbers[nextuglyindex])            ++index5;        ++nextuglyindex;    }    int ugly = puglynumbers[nextuglyindex-1];    return ugly;}

Compared with the first idea, this algorithm does not need to do any computation on the integer of the non-ugly number, so the time complexity is much lower. Of course, we also point out that the second algorithm needs an array because it wants to save the ugly numbers that have already been generated, which requires additional memory. The first algorithm does not have such a memory overhead.


The complete code is as follows:

Before optimization:

#include <stdio.h>bool isugly (int number) {while (number% 2 = = 0) number        /= 2;    while (number% 3 = = 0) number        /= 3;    while (number% 5 = = 0) number        /= 5;    return (number = = 1)? True:false;} int Getuglynumbe (int index) {if (index <= 0)        return 0;    int number = 0;    int uglyfound = 0;    while (Uglyfound < index)    {++number;        if (isugly (number)) ++uglyfound;} return number;} void Main () {int n;while (~scanf ("%d", &n)) printf ("%d\n", Getuglynumbe (n));p rintf ("\ n");}

After optimization:

#include <stdio.h>int puglynumbers[1501];int min (int number1, int number2, int number3) {int Min = (Number1 < numb ER2)?    Number1:number2; Min = (min < Number3)?    Min:number3; return min;}    int getuglynumber (int index) {if (index <= 0) return 0;    Puglynumbers[0] = 1;    int nextuglyindex = 1;    int index2 = 0;    int index3 = 0;    int index5 = 0; while (Nextuglyindex < index) {int min = min (puglynumbers[index2] * 2, PUGLYNUMBERS[INDEX3] * 3, PUGLYNUMBERS[INDEX5] * 5        );        Puglynumbers[nextuglyindex] = Min;while (puglynumbers[index2] * 2 <= puglynumbers[nextuglyindex]) ++index2;        while (PUGLYNUMBERS[INDEX3] * 3 <= puglynumbers[nextuglyindex]) ++index3;        while (PUGLYNUMBERS[INDEX5] * 5 <= Puglynumbers[nextuglyindex]) ++index5;    ++nextuglyindex;    } int ugly = puglynumbers[nextuglyindex-1]; return ugly;} int main () {int n;while (~scanf ("%d", &n)) printf ("%d\n", Getuglynumber (n)); return 0;}

Test results:






Huawei Machine Test-find ugly number (optimized to 20ms)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.