0

This is a CSES problem, named number spiral here, I know this is not the efficient way to do this, but it should however work, Can Someone explain to me why it's partially not working, I even tried the same thing with python its giving me timelimitExceeded

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int T;
    cin >> T; //no of test cases
    while(T--){
        uint64_t x, y; //I also tried using long long, but the output is same
        cin >> x >> y;
        if(x%2==0 && y%2!=0 && y< x){
            cout << fixed <<((x*x)-y)+1 << "\n";
        }else if(x%2==0 && y%2!=0 && y>x){
            cout << fixed << ((y*y)-x)+1 << "\n";
        }else if(x%2==0 && y%2==0 && y<x){
            cout << fixed << ((y*y)-x)+1 << "\n";
        }else if(x%2==0 && y%2==0 && y>x){
            cout << fixed << ((pow((y*y)-1, 2))+x)-1 << "\n";
        }else if(x%2!=0 && y%2==0 && y<x){
            cout << fixed << ((y*y)+x)-1 << "\n";
        }else if(x%2!=0 && y%2==0 && y>x){
            cout << fixed << (pow((y-1), 2))+x << "\n";
        }else if(x%2!=0 && y%2!=0 && y<x){
            cout << fixed << (pow((x-1), 2))+y << "\n";
        }else if(x%2!=0 && y%2!=0 && y>x){
            cout << fixed << ((y*y)-x)+1 << "\n";
        }
    }
    return 0;
}

On input : 689913499 770079066
result : 593021767041187712.000000
instead of : 593021767041187724

KLAUS
  • 21
  • 3
  • 3
    Have you stepped through you code with a debugger? – Stephen Newell Sep 09 '22 at 19:10
  • I know that this specific output is coming from this 3rd last cout line (cout << fixed << (pow((y-1), 2))+x << "\n";) – KLAUS Sep 09 '22 at 19:19
  • _"I know this is not the efficient way to do this"_ - How do you know that you've not come to the same conclusion as everyone else, if your solution differs? – Ted Lyngmo Sep 09 '22 at 19:20
  • 3
    See [Why should I not #include ?](https://stackoverflow.com/q/31816095) and [Why using namespace std is bad practice](https://stackoverflow.com/questions/1452721). – prapin Sep 09 '22 at 19:28
  • fixed the ```include``` and ```namespace``` suggestion, thankyou ! [img](https://www.awesomescreenshot.com/image/32259721?key=ddbfc212844db56af6847cf442fb9293) – KLAUS Sep 09 '22 at 19:55

1 Answers1

5

Using uint64_t to store a 18 digit number

That is reasonable (even a 19 digit number would fit), but it's not what happened, what actually happened is that the pow calls convert the input to a double and also give their result as a double, and a 18-digit number does not quite fit in a double.

Changing the pow calls to a proper integer square fixed the problem for me, at least for this input.

For example:

#include <bits/stdc++.h>
using namespace std;

uint64_t square(uint64_t x)
{
    return x * x;
}

int main()
{
    int T;
    cin >> T; //no of test cases
    while(T--){
        uint64_t x, y;
        cin >> x >> y;
        if(x%2==0 && y%2!=0 && y< x){
            cout << fixed <<((x*x)-y)+1 << "\n";
        }else if(x%2==0 && y%2!=0 && y>x){
            cout << fixed << ((y*y)-x)+1 << "\n";
        }else if(x%2==0 && y%2==0 && y<x){
            cout << fixed << ((y*y)-x)+1 << "\n";
        }else if(x%2==0 && y%2==0 && y>x){
            cout << fixed << ((square((y*y)-1))+x)-1 << "\n";
        }else if(x%2!=0 && y%2==0 && y<x){
            cout << fixed << ((y*y)+x)-1 << "\n";
        }else if(x%2!=0 && y%2==0 && y>x){
            cout << fixed << (square((y-1)))+x << "\n";
        }else if(x%2!=0 && y%2!=0 && y<x){
            cout << fixed << (square((x-1)))+y << "\n";
        }else if(x%2!=0 && y%2!=0 && y>x){
            cout << fixed << ((y*y)-x)+1 << "\n";
        }
    }
    return 0;
}

The result was 593021767041187724, as seen on ideone.

By the way, including bits/std++.h and using namespace std are both generally non-recommended.

harold
  • 61,398
  • 6
  • 86
  • 164
  • 2
    General rule of thumb: when working with integers avoid `pow`. `pow` is a tool built to handle tricky cases like e to the power of pi, so using it to square numbers can be vast overkill. Many compilers and libraries will optimize simple cases, but usually it's just better to multiply. Also note that not even all small numbers can be properly computed. I've seen cases where `int x = 5; x = pow(x,2);` results in an `x` of 24 because pow spat out a close-enough for `double` 24.99999999999999 which gets truncated to fit it in an `int`. – user4581301 Sep 09 '22 at 19:33
  • thank you for taking the time to answer my question.@harold @user4581301 – KLAUS Sep 09 '22 at 19:50
  • @KLAUS harold answered it. I just posted an addendum. – user4581301 Sep 09 '22 at 19:50