Why online judge is giving me an Runtime error? - c++

In the UVA problem "100 The 3n + 1 problem" when i submit the code it says runtime error. The code is in C++
https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
I tried many things but i still cannot solve that problem
#include <iostream>
#include <algorithm>
#define ll long long
#define N 10000
using namespace std;
int main(){
int cont = 0, aux = 0;
ll n1, n2, m;
ll dp[N] = {0};
while (cin >> n1 >> n2) {
cout << n1 << " " << n2 << " ";
if(n1 > n2)
{
m = n2;
n2 = n1;
n1 = m;
}
for (ll i = n1; i <= n2; i++) {
ll num = i;
if (num == 1) {
cont = 1;
}
else{
if (dp[num] != 0){
cont = dp[num];
}
else {
while (num >= 1){
if (num == 1) {
cont += 1;
break;
}
if (num%2 != 0){
num = (3 * num) + 1;
}
else{
num = num/2;
}
cont += 1;
}
dp[num] = cont;
}
}
aux = max(aux, cont);
cont = 0;
}
cout << aux << "\n";
aux = 0;
}
}

The limit on input is 1,000,000 (not 10,000). The limit is stated wrong.
Similar problem:
https://www.spoj.com/problems/PROBTNPO/

Related

Tribonacci number program doesnt return false

For each number read from the standard input the program should print YES if it is a Tribonacci number and NO otherwise. What am I doing wrong in my program, it prints YES, but it wont print NO when the number is not a tribonacci number. For example when number is 45, it should print no.
Tribonacci number formula
T0=0
T1=1
T2=2
Tn=Tn-1 + Tn-2 + Tn-3 (for n>2)
using namespace std;
bool isTrib(int n) {
if(n==0 || n == 1 || n == 2) {
return true;
}
if(n > 2) {
int trib = isTrib(n-1)+isTrib(n-2)+isTrib(n-3);
if(trib == n) {
return true;
}
}
return false;
}
int main()
{
int n;
while(cin>>n) {
bool result = isTrib(n);
cout << result;
result == 1 ? cout << "YES" << endl : cout << "NO" << endl;
}
return 0;
}
you're mixing two things: actual tribonacci numbers and "true"/"false" answer to question "whether N is tribonacci", for example variable trib in your code can be either 0, 1, 2 or 3, it cannot take any other values, but you're trying to compare it with real number, which is apples to oranges
here is fixed version:
bool isTrib(int n) {
if(n==0 || n == 1 || n == 2) {
return true;
}
int n1 = 0;
int n2 = 1;
int n3 = 2;
int trib = n1 + n2 + n3;
while (trib <= n) {
if (trib == n) return true;
n1 = n2;
n2 = n3;
n3 = trib;
trib = n1 + n2 + n3;
}
return false;
}
int main()
{
int n;
while(cin>>n) {
bool result = isTrib(n);
cout << (result ? "YES" : "NO") << endl;
}
return 0;
}

How to eliminate the extra asterisk shown from the prime factorization output?

The following code inputs an integer (n) from the user and outputs the prime decomposition of n. I need to have the following output (as an example), but can't reach it:
Input: 98
Output: 2*7^2
The actual wrong output, which has an extra "*" is:
2*7^2*
^
Maybe there is another solution using functions, which I don't know.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n, countA = 0, countB = 0;
cin>>n;
while(n % 2 == 0)
{
n /= 2;
countA++;
}
if(countA == 1)
cout<<2<<"*";
else if(countA != 0)
cout<<2<<"^"<<countA;
for(int i = 3; i <= sqrt(n); i = i + 2)
{
while(n % i == 0)
{
n /= i;
countB++;
}
if(countB == 1)
cout<<i<<"*";
else if(countB != 0)
cout<<i<<"^"<<countB<<"*";
}
if(n > 2)
cout<<n;
return 0;
}
Instead of unconditionally printing it:
cout<<i<<"^"<<countB<<"*";
You could test if it's the last number. Example (apply everywhere where it's needed):
for(int i = 3, end = sqrt(n); i <= end; i = i + 2) {
// ...
cout << i << '^' << countB;
if(i + 2 <= end) cout << '*';
So one of the possible solutions to my question, according to #Jonathan Leffler's comment is as follows:
#include <iostream>
#include <cmath>
using namespace std;
const char *pad = "";
int main()
{
int n, countA = 0, countB = 0;
cin>>n;
while(n % 2 == 0)
{
n /= 2;
countA++;
}
if(countA > 0)
{
cout<<pad;
cout<<2;
if(countA > 1)
{
cout<<"^"<<countA;
}
pad = "*";
}
for(int i = 3; i <= sqrt(n); i = i + 2)
{
countB = 0;
while(n % i == 0)
{
n /= i;
countB++;
}
if(countB > 0)
{
cout<<pad;
cout<<i;
if(countB > 1)
{
cout<<"^"<<countB;
}
pad = "*";
}
}
if(n > 2)
{
cout<<pad;
cout<<n;
pad = "*";
}
return 0;
}

How can I make my c++ program to countinue?

I wrote this to find out which 10-digit numbers are prime but it stops after showing about 20 numbers at all. Would you help me figure out what's wrong? Or suggesting any other sources? It's important to me as it's my school project.
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
void temp()
{
static long long n1=9999999999 ;
long long n2,n3;
if (n1 <= 1 || n1%2==0|| n1%3==0|| n1%5==0|| n1%7==0|| n1%11==0|| n1%13==0|| n1%17==0|| n1%19==0|| n1%23==0|| n1%29==0|| n1%31==0|| n1%37==0|| n1%41==0|| n1%43==0|| n1%47==0|| n1%53==0|| n1%59==0|| n1%61==0|| n1%67==0|| n1%71==0|| n1%73==0|| n1%79==0|| n1%83==0|| n1%89==0|| n1%97==0)
{
std::cout<< n1 << " not prime\n\n";
n1--;
temp();
}
else
{
n2 = (n1 - 1)/2;
while (n2 > 1)
{
n3 = n1 % n2;
if (n3 == 0)
{
std::cout<< n1 << " not prime\n\n";
}
else
{
n2--;
}
}
std::cout<< n1 << " prime\n\n";
n1--;
temp();
}
}
int main(int argc, char** argv)
{
temp();
return 0;
}
When n1 is 9999999983 it gets stuck inside the while loop until n2 is less or equal to 1
You should look for a more efficient way
while (n2 > 1)
{
n3 = n1 % n2;
if (n3 == 0)
{
std::cout << n1 << " not prime\n\n";
n1--;
temp();
}
else
{
n2--;
}
}
EDIT:
This is what you could do in your case (Found it here and changed it to fit your needs (I found it here and changed it up a bit to fit your needs)
#include <iostream>
using namespace std;
void check() {
int n = 9999999999;
while (n != 0) {
int i, m = 0, flag = 0;
m = n / 2;
for (i = 2; i <= m; i++)
{
if (n % i == 0)
{
cout << "Number is not Prime." << endl;
flag = 1;
break;
}
}
if (flag == 0)
cout << "Number is Prime." << endl;
n--;
}
}
int main()
{
check();
return 0;
}

Finding total of prime numbers between two x1,x2, cant find mistake?

I need to find the sum of prime numbers between two numbers, say x1 and x2 inclusively, however i cant detect whats wrong?
for example if i entered 3 and 9 i would get 15 but i am getting 133!
#include <iostream>
using namespace std;
int prime(int n1, int n2)
{
int count =0;
bool prime = true;
for (n1; n1 < n2; n1++)
{
for (int i = 2; i < n1; i++)
{
if (n1 % i == 0) {
prime = false;
continue;
}
else
count++;
}
}
return count;
}
int main()
{
int n1, n2;
cout << " Enter values for n1 and n2 (n1 must be smaller than n2): ";
cin >> n1>>n2;
cout << " Sum of prime numbers from " << n1 << " and till " << n2 << " inclusively : " << prime(n1, n2) << endl;
system("pause");
return 0;
}
Your prime function is not appropriate. This should be like.
int prime(int n1, int n2) {
int sum = 0;
for (n1; n1 < n2; n1++) {
bool prime = true;
for (int i = 2; i < n1; i++) {
if (n1 % i == 0) {
prime = false;
break;
}
}
if( prime ) { // current n1 is prime
sum = sum + n1;
}
}
return sum;
}
You are not adding anything if your n1 is prime.
I am a big believer in the one loop per function. This is a very good example for this. Your inner loop checks if a number is prime so really it should be a function on its own:
bool is_prime(int n);
int sum_primes_between(int n1, int n2)
{
int sum = 0;
for (; n1 <= n2; n1++)
{
if (is_prime(n1))
sum += n1;
}
return count;
}
Now not only it's easier to read, but you can better test individual parts of code. You can test that is_prime is correct and after that you can test num_primes_between is correct. If you had gone this route from the start you wouldn't even have had the bug you currently have with detecting if a number is prime.
And here is an even neater solution with range-v3:
using namespace ranges;
bool is_prime(int n);
int sum_primes_between(int n1, int n2)
{
return accumulate(view::ints(n1, n2 + 1) | view::filter(is_prime), 0);
}
None of the answers provided so far respect the requirement of being inclusive.
Here's a corrected version including an optimized algorithm to check for primality:
#include <iostream>
#include <cmath>
using namespace std;
bool is_prime(int n) {
// handle special cases
if (n <= 1) {
return false;
}
if (n <= 3) {
return true;
}
if (n % 2 == 0 || n % 3 == 0) {
return false;
}
/* because we covered multiples of 2 and 3 we can reduce the number of checks
drastically */
for(int i = 5, r = sqrt(n); i =< r; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
int sum_of_primes(int n1, int n2) {
int sum = 0;
// loop from n1 up to n2
for ( ;n1 <= n2; n1++) {
if (is_prime(n1)) {
sum += n1;
}
}
return sum;
}
int main() {
cout<<"The sum of primes between 2 and 15 is: "<<sum_of_primes(2,15)<<endl;
return 0;
}
Your original code didn't calculate the sum of primes, you simply incremented your count variable on every iteration that didn't find a divisor of the current number you were checking.

Wrong Solution if Memoization is added to Recursion

I have created a DP program but the problem is that I get correct answers when I don't use memoization. As soon as I introduce memoization, I start getting the wrong answers for some problems
Here is the code in C++ 14 with memoization turned off (By commenting)
#include <iostream>
#include <math.h>
#include<algorithm>
using namespace std;
int max_Number_of_turns;
int dp[9999][1000];
int changeTheDigit(int n, int d) {
int rem = n % (int) (pow(10, 4 - d));
n /= (pow(10, 4 - d));
int x = n % 10;
n /= 10;
if (x == 9) x = 0;
else x = x + 1;
n = n * (10) + x;
n = n * (pow(10, 4 - d)) + rem;
return n;
}
int minMax(int n, int t) {
int ans =0;
//if(dp[n][t]>=0) { return dp[n][t];}
if (t > max_Number_of_turns) return n;
int N;
for (int i = 0; i < 4; i++) {
N = changeTheDigit(n, i + 1);
if (t % 2 == 0) {
//Manish chance
if(ans==0) ans=minMax(N, t+1);
else ans = min(ans, minMax(N, t + 1));
} else {
//Nitish Chance
ans = max(ans, minMax(N, t + 1));
}
}
//cout << ans << endl;
dp[n][t]=ans;
return ans;
}
using namespace std;
int main() {
int T, N, M;
cin >> T;
while (T--) {
cin >> N >> M;
max_Number_of_turns=M;
for(int i=0;i<9999;i++)
for(int j=0;j<1000;j++)
dp[i][j]=-1;
if(minMax(N,1)>N){
cout << "Nitish" << endl;
}
else{
cout << "Manish" << endl;
}
}
return 0;
}
Turn the memoization comment on (i.e. remove the comments from this line)
if(dp[n][t]>=0) { return dp[n][t];}
and my code will give wrong answers to some problems
For example, let us consider the input
1
4569 12
Original Correct Solution is Manish
But If I turn on memoization, My solution is Nitish
Can you suggest me that what am I doing wrong here
Also, a fun fact is that, if the change the DP code from
if(dp[n][t]>=0) { return dp[n][t];}
to
if(dp[n][t]>0) { return dp[n][t];}
Then everything is fine
Your problem is that the values for n and/or t are not checked and so could cause out-of-bounds issues with the array. You can see that if you insert the following at the start of your minMax function:
if (n < 0 || n >= 9999) cout << "n invalid at " << n << '\n';
if (t < 0 || t >= 1000) cout << "t invalid at " << t << '\n';
Running that with your sample input gives warnings before outputting the result:
n invalid at 9999
n invalid at 9999
n invalid at 9999
To fix this, you can just ensure you only use memoisation when you have enough storage for it, first when checking the value:
if (n >= 0 && n < 9999 && t >= 0 && t < 1000 && dp[n][t] >= 0)
return dp[n][t];
and, second, when storing the value:
if (n >= 0 && n < 9999 && t >= 0 && t < 1000)
dp[n][t] = ans;