开发者

C#: Wrong answer when finding "cool" numbers

In my application, a "cool" number is a number that is both a square and a cube, like for example: 64 = 8^2 and 64 = 4^3. My application is supposed to find the number of "cool numbers" between a range given by the user. I wrote my code and the application runs fine, but it is giving me the wrong answer. Can you help me here please? for example:

INPUT

1 100

OUTPUT

1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static voi开发者_Python百科d Main(string[] args)
        {
            double a = Convert.ToDouble(Console.ReadLine()); // first number in the range
            double b = Convert.ToDouble(Console.ReadLine()); // second number in the range
            long x = 0;
            for (double i = a; i <= b; i++)
            {   

                   double cube = 1.0 / 3.0;
                   double cuad = 1.0 / 2.0;
                   double crt = Math.Pow(i, cube); // cube root 
                   double sqrt = Math.Pow(i, cuad); // square root


                if ((crt * 10) % 10 == 0 || (sqrt * 10) % 10 == 0) // condition to determine if it is a cool number.
                    x++;

            }
            Console.WriteLine(x);
            Console.ReadLine();
        }
    }
}


"Cool numbers" is a rather roundabout way of describing sixth powers. Clearly every sixth power is a cool number; x^6 is (x^2)^3 and (x^3)^2. And every number that is not a sixth power is not a cool number. (Proof is left as an exercise. Hint: consider the necessary properties of any prime factorization of a cool number.)

Therefore I would simply write a device which enumerates the sixth powers that are in a range.


doubles are messy in most languages. They often get stored imprecisely, giving you the wrong answer sometimes. You don't want to use them when you don't have to.

Here's how I would do it. Take two ints from the user. Loop through the integers in the range of those two ints (like you're doing with your floats.) For each one, find the cube root and square root and store them in doubles. Then round the cube root and square roots to the nearest integer (using a library function) and store them as ints. Finally, to see if the current number is a square or cube, multiply the square root int by itself and the cube root int by itself by itself, and see if those two products equal the original number. If they do, you have a cool number.

This way, the rounding function is sure to sift out any precision errors in your doubles, and then all your numbers are nice and sound.

Some code:

int a = int_from_user();
int b = int_from_user();

for (i = a; i <= b; i++) {
  int sqrt = round(sqrt(i));
  int cbrt = round(cbrt(i));

  if (sqrt * sqrt == i && cbrt * cbrt * cbrt == i) {
    cool++;
  }
}


The || operator is meant to evaluate to true if one of the parts is true, so your condition will evaluate to true whether is exact cube OR exact square if ((crt * 10) % 10 == 0 && (sqrt * 10) % 10 == 0)

This is another option, a bit slow but you can test it:

if (((crt == Math.Floor(crt)) && (sqrt == Math.Floor(sqrt))) x++;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜