Segmentation fault for higher values of n(e.g n=999997) - c++

I am using dynamic programming for a problem where I will be given n and need to output minimum number of operations to get 1 from n by using these three operations( -1 ,/2 ,/3). Given constraint(1<=n<=10^6)
My code is giving segmentation fault(somewhere in solve function) for higher values of n(e.g 977775,1000000) but running fine of smaller input(e.g 100000).
I have tried a lot but I am unable to find problem in my code. Also is there any other way I can apply dynamic programming in this question.
Any help would be appreciated.
#include<iostream>
using namespace std;
int solve(int n,int a[])
{
if(n==1)
return 0;
if(a[n]!=-1)
return a[n];
int ans=100000;
for(int i=0;i<3;i++)
{
if(i==0)
{
a[n]=solve(n-1,a)+1;
if(a[n]<ans)
ans=a[n];
}
else if(i==1 && n%2==0)
{
a[n]=solve(n/2,a)+1;
if(a[n]<ans)
ans=a[n];
}
else if(i==2 && n%3==0)
{
a[n]=solve(n/3,a)+1;
if(a[n]<ans)
ans=a[n];
}
}
return ans;
}
int main()
{
int n;
cin>>n;
int a[n+1];
for(int i=0;i<=n;i++)
a[i]=-1;
int ans=solve(n,a);
cout<<ans<<endl;
return 0;
}

The problem is that you can only store up to 8 digits in an int variable in C++, I would switch from int ans to double ans to fix the problem, also keep in mind that double can store up to 34 digits, if you try to do store more digits than the maximum allowed number of digits, weird things happen, and in that case you get a stackOverflow..... Also consider the following: In your function, you are calling about 999997 recusive calls * 3 which is about 3000000 recusive calls for the stack, which is going to use way too much memory and hence Segmentation fault.....

Related

what if I used 2 map in a c++ program and the key values I used to store their frequency in the 2 different operation are same

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define rep(i,a,b) for(ll i=a;i<b;i++)
void calculation(ll n,ll x)
{
ll i,arr[n],k,max=INT_MIN,j=0,min=INT_MAX;
map<ll,ll> m1,m2;
rep(i,0,n)
{
cin>>arr[i];
m1[arr[i]]++;
}
if(x==0)
{
rep(i,0,n)
{
if(m1[arr[i]]>max)
max=m1[arr[i]];
}
cout<<max<<" 0\n";
}
else{
rep(i,0,n)
{
if(m1[arr[i]]+m2[arr[i]]>=max && m2[arr[i]]<min){
max=m1[arr[i]]+m2[arr[i]];
min=m2[arr[i]];}
}
cout<<max<<" "<<min<<"\n";
}
}
int main ()
{
ll t,n,x;
cin>>t;
while(t--)
{
cin>>n>>x;
calculation(n,x);
}
return 0;
}
In the above code i used to map,one to store the intial frequency of numbers and second to store the frequency of numbers xor 'X'.
This question is from codechef september long challenge and giving wrong answer.I am not asking answer ,but I want to clear my concepts of maps . Also I am providing the link of question if anyone want to try it.
https://www.codechef.com/SEPT21C/problems/PALINT
if the key is same ,then if we increment in map 2,does it also get incremented in map 1.
pls help !. I got stuck here.
The answer is No. The two map is different from each other. They don't share memory. You should print address of value or key of the two map for more details.

Find ways an Integer can be expressed as sum of n-th power of unique natural numbers.code giving wrong output

I have t test cases.
Given two numbers x and n, find number of ways x can be expressed as sum of n-th power of unique natural numbers.
The approach is to either select a number or move to the next one.The ans returned is stored in an array since I am using the dp approach.
This is my code
#include<bits/stdc++.h>
using namespace std;
int arr[101];
int func(int x,int n,int ind)
{
if(arr[x]!=-1)
{
return arr[x];
}
if(x==0)
{
return 1;
}
if(ind>=(sqrt(x)+1))
{
return 0;
}
if(x<0)
{
return 0;
}
//you can either take ind or just move to the next one
arr[x]=func(x-pow(ind,n),n,ind+1)+func(x,n,ind+1);
return arr[x];
}
int main()
{
int t;
cin>>t;
while(t)
{
int ans=0;
memset(arr,-1,sizeof(arr));
int x,n;
cin>>x>>n;
int ind=1;
ans=func(x,n,ind);
cout<<"printing the ans\n"<<ans;
t--;
}
return 0;
}
for input
1
10 2
I am getting
printing the ans
-297160607
though the ans is 1
I inserted a simple debug output in func. For the given input "1 10 2" x sometimes gets negative. This causes UB when accessing the array, but does not necessarily crash.
You already check if x is less than 0, but after using x. Move the if(x < 0) up and you are done.
In general to avoid such mistakes you should use stl containers like std::array or std::vector. Though it is not garantued by the c++ standard, many implementations will performe bounds checking on operator[] when compiled in debug mode. Or you can use at() where the standard garantuess bounds checking.

SIGABRT error for - https://www.codechef.com/problems/PRIME1

I am using sieve of eratosthenes to solve this problem but it is giving me SIGABRT error although my code is working fine on codeblocks....
Please help me modify this code to remove error....
My code is...
#include<vector>
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace std;
int main()
{
unsigned long int t, n, m,i,j;
vector<int> prime;
cin>>t;
while(t--)
{
cin>>m;
cin>>n;
while(!(1<=m&&m<=n&&n<=1000000000&&n-m<=100000))
cin>>m>>n;
prime.resize(n);
for(i=0;i<n;i++)
prime[i]=1;
prime[0]=0;
prime[1]=0;
for(i=2;i<sqrt(n);i++)
{
if(prime[i]==1)
{
for(j=i;i*j<=n;j++)
prime[i*j]=0;
}
}
for(i=m;i<=n;i++)
{
if(prime[i]==1)
cout<<i<<endl;
}
cout<<endl;
prime.resize(0);
}
return 0;
}
Your j loop allows i*j to equal n, but the vector of size n must be indexed from 0 to n-1. The existing code permits referencing an element out of bounds.
The same problem can occur in the last loop, too.
The SIGABRT is issued by library routines.
You have two library routines in your program: std::vector and sqrt.
Either assign sqrt(n) to a const variable or replace the condition with:
(i * i) < n;
You need to verify that:
prime[i*j]
is a valid location. In other words, (i * j) < n.
Some information about primes (that can help you code your program):
Prime numbers are odd except the value 2.
Your test value can start at 3 and add 2 to get to the next value.
You may be able to save some time by looking values in an array of
known values.
Multiplication is usually faster than division. Try rewriting your
test to use multiplication and not division.
Use a data type that can contain the maximum value.

3n+1 on UVa (C++)

The link to the 3n+1 problem on UVa is:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
My code is :
#include<iostream>
using namespace std;
long long l(long long n)
{
if(n==1)
{
return 1;
}
if(n%2)
{
return 1+l(3*n+1);
}
else
{
return 1+l(n/2);
}
}
int main()
{
long long i,j,k,max=0,f,g;
while(!cin.eof())
{
cin>>i>>j;
f=i;
g=j;
if(i>j)
{
long long temp;
temp=i;
i=j;
j=temp;
}
max=0;
for(long long a=i;a<=j;a++)
{
k=l(a);
if(k>max)
{
max=k;
}
}
cout<<f<<' '<<g<<' '<<max<<'\n';
}
return 0;
}
To explain my code, I'm using simple recursion.
The input is taken as i, j and is preserved as it is using f, g respectively.
i and j are swapped explicitly using temp. max is set 0 in every test case. k is used to hold the result sent by length function l() and is tested with max which stores maximum length till now.
My solution passes all the given trivial test cases in the problem.
It even passes all the tricky test cases which involve i greater than j and i==j
The problem hides integer overflow by giving incomplete information about requirement of long. I even handled that. The output rquires i, j in same order. The input gives no explicit end. I handled all of them. But still am getting wrong answer.
Your code is okay.
The only problem is your input handling untill End of File.
Just change while(!cin.eof()) to while(cin>>i>>j). You will get AC :)
May be problem with '\n'? Try to use cout<<f<<' '<<g<<' '<<max<<endl;

Wrong number of iterations in for loop.Also getting unexpected output

Codeforces problem 160A-http://codeforces.com/problemset/problem/160/A
I am getting either 1 or 2 as the output for all test cases.I think this is because the for loop at the end of the solution is only running either once or twice only.I am not able to identify why is the loop ending after atmost 2 iterations.What is wrong with my solution.
My solution:
#include<iostream>
using namespace std;
int total(int x,int y,int array[100]) //Function to calculate sum of xth to yth term of array.
{
int z=0;
for(int a=x;a<=y;a++)
{
z+=array[a];
}
return z;
}
int main()
{
int n,coin[],sum1,sum2,i,j,a,temp,noofcoins;
cin>>n;
for(i=0;i<n;i++)
cin>>coin[i];
for(i=0;i<n;i++) //Bubble sorting array in descending order.
{
for(j=0;j<n-i-1;j++)
{
if(coin[j]<coin[j+1])
{
temp=coin[j];
coin[j]=coin[j+1];
coin[j+1]=temp;
}
}
}
noofcoins=0;
sum1=0;
sum2=0;
for(i=0;((i<n)&&(sum1<=sum2));i++)
{
sum1+=coin[i];
sum2=total(i+1,n,coin);
++noofcoins;
}
cout<<noofcoins;
}
First, avoid using global variables. This declaration belongs to the main body
int n,coin[100],sum1,sum2,i,j,temp,noofcoins;
Once you correct it you'll notice the variable i used in the function totalis the same as the one used in main. Just initialize it in the for.
for(int i=x;i<y;i++)
Then, the condition in the final for is wrong. It should be:
for(i=0;((i<n)&&(sum1<=sum2));i++)
You have defined i as a global variable.
You use i both in the function total as in main where you use i for the loop where you call total. So after you called total, i has become a different value, and the loop in main will end.
U have declared i as a global variable and then u are using it at two places and then that's certainly causing the problems
1-there's no reason to declare your variables globally, it's better to declare them in your main() function.
2-Your way of bubble sorting seems to be wrong. The correct way is to sort the bubble until there's no swapping required.
bool flag=flase;
while (!flag){
flag=true;
for(i=0;i<n-1;i++){ //Bubble sorting array in descending order.
if (coin[i]<coin[i+1]){
temp=coin[i];
coin[i]=coin[i+1];
coin[i+1]=temp;
flag=false;
}
}
}
3-your way of passing an array to a function is incorrect. Read the part "Arrays as parameters" on this page for the right way.
4-Finally, you might want to use "new" function to create your array. This way it will not be limited to your maximum array size of 100, and also won't waste memory when your array is smaller than 100.
Read here for learning to use "new" function.
following may help:
int twin(std::vector<int> coins)
{
std::sort(coins.begin(), coins.end());
const int total = std::accumulate(coins.begin(), coins.end(), 0);
int left = total;
int right = 0;
for (size_t i = 0; i != coins.size(); ++i)
{
const int value = coins[coins.size() - 1 - i];
left -= value;
right += value;
if (right > left) {
return 1 + i;
}
}
return 0;
}