0

Question:
A circle of radius R cm is touching both the positive axes i.e., the X-axis and the Y-axis. There is another circle touching both the axes as well as the previous circle. Note that this circle won't have the same center as the original circle. The question is to find the sum of squares of the radius of all the circles that satisfies the condition.

#include <stdio.h>
#include <math.h>

int roundNo(double num) 
{ 
    return (int)(num + 0.5);
} 
    
int main()
{
    double multiplier1 = 2*sqrt(2) + 3;
    double multiplier2 = 1/multiplier1;
    int t;

    scanf("%d",&t);

    for (int i = 0; i < t; i++) {
        double sum;
        int n;
            
        scanf("%d", &n);
        sum = (2 + pow(multiplier1, 2) + pow(multiplier2, 2))*pow(n, 2);
            
        printf("%d\n", roundNo(sum));
    }
}

We have to print the integer sum for the test cases. So I have rounded them off.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Like this? https://share.sketchpad.app/21/d02-98f7-ecb2de.png :-) – pmg Feb 07 '21 at 11:56
  • No but you are close. We have to get circles which touch each other and the axes as well. – Adrishyantee Maiti Feb 07 '21 at 11:58
  • Better like this? https://share.sketchpad.app/21/a5d-3d9b-e6aa7d.png – pmg Feb 07 '21 at 12:03
  • 1
    This is more like a math problem. Anyway if I'm thinking right you'll have two circles for a given R, then the '2' in the sum should be omitted – morimn Feb 07 '21 at 12:03
  • @pmg They will touch and not cut – Adrishyantee Maiti Feb 07 '21 at 12:05
  • @Adrishyantee Maiti - Why do you think the solution is only integers? What do you mean by _all the circles_ - all circles of radius R, all _another circle_, all pairs of circles, or what? What do you mean by _the condition_? What is _t_? What is _n_? With which values did you test? – Armali Feb 07 '21 at 12:11
  • The condition is that the circle touches both axes in addition to the original circle. If I'm not mistaken this means there are 2 circles that meet that criterion which are both versions of the original circle scaled with the intersection of the axes as pivot point. I don't get where the 2 in `sum = ...` comes from though. – fabian Feb 07 '21 at 12:18
  • @Armali The solution expects us to output integers. And by all the circles I mean all the different types of circles formed keeping the condition in mind. Condition is that Circles must touch the given circle and the axes. T is number of testcases. N is the radius of circle to be given as input. Values with which I am testing isn't shown to us. Its predefined. – Adrishyantee Maiti Feb 07 '21 at 12:22
  • @fabian Try to solve it with equations You might get the expression as 36 for circle of radius 1 cm – Adrishyantee Maiti Feb 07 '21 at 12:23
  • 1
    I indeed tried to solve the equations and got the radius of the larger circle as `(2*sqrt(2)+3) * R = multiplier1 * R` and the radius of the smaller circle as `R / (2*sqrt(2)+3) = R * multiplier2` which means the correct formula would be `(multiplier1*multiplier1 + multiplier2*multiplier2)*R*R` – fabian Feb 07 '21 at 12:28
  • @AdrishyanteeMaiti *So I have rounded them off* -- `return (num -(int)num) < 0.5` -- Have you considered that this will not work if the `num` is `3.4999999`, when the hand-computed result should have been `3.5`? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). Just this alone will cause test failures. – PaulMcKenzie Feb 07 '21 at 12:32
  • @PaulMcKenzie yes I have not considered it. Thank you. – Adrishyantee Maiti Feb 07 '21 at 12:55
  • @PaulMcKenzie can you tell me how to avoid this error. I am not getting it. – Adrishyantee Maiti Feb 07 '21 at 12:58
  • @fabian When we put R =1 we don't get 36. Do we? – Adrishyantee Maiti Feb 07 '21 at 13:01
  • @AdrishyanteeMaiti You can try [std::round](https://en.cppreference.com/w/cpp/numeric/math/round). But in general, if this question comes from one of those online coding sites, I suggest you figure out what test cases actually fail and get the data. If indeed the issue is that rounding doesn't work, even if the answer is correct, then this is an artifact of floating point not being exact. Questions that want the output rounded are ones that will always have those one or two failures that will never work, unless you use an exact type in your calculations instead of `double`. – PaulMcKenzie Feb 07 '21 at 13:04
  • @PaulMcKenzie The test cases are not visible. but I can give you the question. A circle of radius R cm is touching both the positive axes i.e., the X-axis and the Y-axis. There is another circle touching both the axes as well as the previous circle. Note that this circle won't have the same centre as the original circle .Find the sum of squares of the radius (in cm2) of all the circles that satisfies the above condition. Input: The first line contains a single integer T denoting the number of test cases. Each test case contains a single integer R. – Adrishyantee Maiti Feb 07 '21 at 13:23
  • @PaulMcKenzie For each testcase, print a single line containing an integer – the sum of squares of the radius of all the circles that satisfies the above condition. Constraints 1≤T≤10^5 1≤R≤10^8 Sample Input: 1 1 Sample Output: 36 – Adrishyantee Maiti Feb 07 '21 at 13:23
  • 1
    @AdrishyanteeMaiti I don't know where this 1cm -> 36 keeps coming from, but this answer is simply wrong. Solving the equation for two circles has no +2 factor anywhere. I suspect maybe there is an error in the problem itself. – morimn Feb 07 '21 at 13:36
  • Right, with the (I think) correct formula given by fabian, I get 34 for R=1. – Armali Feb 07 '21 at 14:19

2 Answers2

0

I think that your problem is like below: enter image description here

This is the math problem, not the programming.
enter image description here

Now there are two ways. One approach is

#include <stdio.h>
#include <math.h>

const double multiplier = 1.030330085889911;

int round(double num)
{
    return (int)(num + 0.5);
}

int main()
{
    int R0;
    printf("Input R0: ");
    scanf("%d", &R0);

    double S = pow((double)R0, 2) / (sqrt(2.0) * 12 - 16);
    printf("S = %d\n", round(S));

    return 0;
}

The other is more programmatically

#include <stdio.h>
#include <math.h>

const double threshold = 0.001;

int round(double num)
{
    return (int)(num + 0.5);
}

int main()
{
    int R0;
    printf("Input R0: ");
    scanf("%d", &R0);
    
    int i = 0;
    double Ri = R0;
    double S = R0 * R0;

    while (Ri > threshold)
    {
        i++;
        Ri = (3.0 - 2.0 * sqrt(2.0)) * Ri;

        S+= (Ri * Ri);
    }

    printf("i: %d, Ri: %f, S = %d\n", i, Ri, round(S));
    return 0;
}
secuman
  • 539
  • 4
  • 12
0

While this is just a tricky math problem, there are many issues in the posted implementation.

The formula is (analitically) correct, if we consider all the four circles touching both the axes as well as the original circle:

all the circles

The posted code failed to perform some fundamental simplifications, though.

  • The requested sum is obtained by multipling the square of the inputted radius times a constant, indipendent from said radius. While an optimizing compiler might be smart enough not to repeat all theese calculations, it would be better (at least for documentation purposes) to explicitly calculate this multiplier once and store its value in a const or constexpr variable.

  • The value of this multiplier is exactly 36 (the test case already told us), so there's no need to use a double nor to round floating point values:

multiplier formula

The main issue, however, is a pure coding bug.

One of the constraints of the problem (from OP's comments) is 1 ≤ R ≤ 10^8, but the result is returned by roundNo as int, which isn't required to be a 64-bit wide type.

It's more than likely that some test cases had a value of the radius big enough to produce a sum bigger than the maximum value storable in an int, introducing undefined behaviour.

The following should work for all the test cases.

long long sum = 36LL * radius * radius;

Note that, thanks to the integer literal and its LL suffix, even if radius was an int (or a long, to be sure), it would be converted to a long long before beeing multiplied by itself. Also, there's no need to use pow and deal with floating-point types.

Bob__
  • 12,361
  • 3
  • 28
  • 42