3n+1 on UVa (C++) - 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;

Related

Can't seem to find the error - memory access violation

I'm trying to solve a problem on france IOI about a card game (named "Reussite" on level 4) that requires outputting every odd number, however I keep getting (0xC0000005) code if my input is bigger than about 48000 and I can't seem to find the error. Help!
here's my code:
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
int n;cin>>n;vector<int> arr(n+1);
for (int i = 2; i < n+1; ++i) {
int m = i;
//error is in this while loop
while (i*m<=n){arr[i*m]=1;m++;}
}
for (int i = 0; i < n+1; ++i) {
if (arr[i]==0) printf("%d \n",i);
}
}
When the value n is at least 46341, its square no longer fits into a 32-bit signed integer, so the expression i*m results in an integer overflow.
You might want to cast the values to long long, like while ((long long)i*m<=n) or while (i*1LL*m<=n), or change your code otherwise.

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

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.....

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.

Error in program for modified bubble sort

Codeforces problem 339A-http://codeforces.com/problemset/problem/339/A
I have tried to sort the values stored at even places of the array(starting from 0).I get an error while running the program or program returns a junk value.What is wrong with my solution?
My solution:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char s[101],temp;
int i,j;
cin>>s;
for(i=0;i<strlen(s);i+=2) //Bubble sorting values at even values of i.'+' is stored at odd values of i.
{
for(j=0;j<(strlen(s)-i-2);j+=2)
{
if(s[j]>s[j+2])
{
temp=s[j];
s[j]=s[j+2];
s[j+2]=temp;
}
}
}
cout<<s;
}
Your compiler should have warned you about the problem (you did switch on all warnings, yes? always do that!): Once i==strlen(s)-1, the loop for j is essentially unbounded, by the magic of arithmetic rules for signed/unsigned values.
for(unsigned j=0; j+2+i < strlen(s); j+=2)
does not have this problem. (i should be unsigned as well.)
Or stop the loop for i earlier. The problem in your code is still there then, but you won’t run into it. But I believe that is the worse route to take – fix the bug, and then optimize by observing i doesn’t need to go as far up, because the last character already forms a sorted sequence.
For odd lengths len of s, the outer loop runs until i==len-1. The inner loop then terminates at len - len - 1 - 2. Since strlen returns an unsigned type, this evaluates to a very large unsigned number, causing the inner loop to read way beyond the end of s. Eventually you'll reach memory you don't have access to read or write, causing the crash.
You can fix this by ending the outer loop sooner
int len = strlen(s);
for(i=0;i<len-2;i+=2) {
for(j=0;j<(len-i-2);j+=2)
Change this:
for(i=0;i<strlen(s);i+=2)
Into this:
for(i=0;i<strlen(s) - 2;i+=2)
Otherwise the s value be handled beyond its end-point
here is my code
void bubble(int a[], int n){
for(int i=0; i<n; i++){
int swaps=0;
for(int j=0; j<n-i-1; j++){
if(a[j]>a[j+1]){
int t=a[j];
a[j]=a[j+1];
a[j+1]=t;
swaps++;
}
}
if(swaps==0)
break;
}
}