SPOJ Prime generator Wrong Answer - primes

Here is the link to the problem-:http://www.spoj.com/problems/PRIME1/.
The problem asks to find all prime numbers between a given rang
1 <= m <= n <= 1000000000, n-m<=100000.
I have implemented Segmented Sieve
Here is the logic-:
As the problem has maximum value of 10^9, so I will find all primes withing square_root(10^9) which is around 31622.
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
void Prime1(long int low, long int high, bool* pre)
{
bool prime[high-low+1]={0};
if(low==high)
{if(pre[low]==0)printf("%ld\n", low);return;}
int t=sqrt(high);
for(long int i=2;i<=t;i++)
{
if(pre[i]==1)continue;
long int a=ceil(((double)low/i))*i;// start value
long int b=floor(((double)high/i))*i;// end value
if(a==1)
continue;
if(a==i)
a+=i;
if(a==0)
a=2*i;
for(long int x=a;x<=high;x+=i)
{
prime[x-low]=1;
}
}
if(low==1)
prime[0]=1;
else if(low==0)
prime[0]=prime[1]=1;
for(int i=0;i<=(high-low);i++)
if(!prime[i])printf("%ld\n", i+low);
}
int main()
{
bool pre[32001];
pre[0]=pre[1]=1;
int x=sqrt(32001);
for(int i=2;i<=x;i++)
{
if(pre[i]==0)
{
for(int j=i;i*j<=32000;j++)
{
pre[i*j]=1;
}
}
}
int t;
scanf("%d",&t);
long low, high;
while(t--)
{
scanf("%ld %ld",&low, &high);
printf("\n")
Prime1(low, high, pre);
}
}
Now I'll start from i=2 and find its multiples between m and n. Here m and n represent low and high respectively.
I'll keep on increasing i till i<=sqrt(n)
For example, m=125 and n=140
a=((double)m/i)*i. I'll consider its ceiling value.
So, when m=125 i=2
a=126.
so, 126+(2*k) are all composite where k>=0.
The same is for i=3,5,7.....
When I submit it on SPOJ, it gives me WA.
I have used spoj toolkit which contained some test cases. I compared it with the other code and getting same result.
What am I missing?

Related

Why is my Sliding Window algorithm not providing correct answers?

The problem is from a recent competition on Codechef.
According to the problem, for a given array of length N, find the maximum average of the numbers of any contiguous sub-array of length between A and B.
Now here is the logic that I have used. I have in a loop iterated over the possible contiguous sub-array length K from A to B. Then for every such K, I have used the sliding window mechanism to find the maximum sum of contiguous
elements of the array. Then I check if the already stored answer (the average) is smaller than the current maximum/K and update the answer.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,b,a;
cin>>n>>b>>a;
long long arr[n+1];
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
double ans=0;
for(int k=a;k<=b;k++)
{
long long maxi=0;
for(int i=1;i<=k;i++)
{
maxi=maxi+arr[i];
}
long long l=maxi;
for(int i=k+1;i<=n;i++)
{
l=l+arr[i]-arr[i-k];
maxi=max(maxi,l);
}
double x=(double)(((double)(maxi))/(double)(k));
ans=max(ans,x);
}
cout<<ans<<endl;
}
}
However, after implementing my logic over as shown, I am getting wrong answers even though I do not know how different they are the actual answer since I have not obtained anything wrong in my processes of debugging.
The following is an edit:
Are my previous code and the following the same?
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,b,a;
cin>>n>>b>>a;
long long arr[n+1];
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
long double ans=0;
for(int k=a;k<=b;k++)
{
long long l=0;
for(int i=1;i<=k;i++)
{
l=l+arr[i];
}
ans=max(ans,(long double)(((long double)(l))/(long double)(k)));
for(int i=k+1;i<=n;i++)
{
l=l+arr[i]-arr[i-k];
ans=max(ans,(long double)(((long double)(l))/(long double)(k)));
}
}
cout<<ans<<endl;
}
}
Thanks for helping guys. I tried out the following and it sort of works:
cout<<fixed<<setprecision(10);
setprecision(10)

Google code jam minimum scalar product not working on my selection sort (c++)

I was practicing previous year's code jam problems and found minimum scalar product.
Problem Link : https://code.google.com/codejam/contest/32016/dashboard#s=p0
I know how its algorithm works. We sort both arrays v1 and v2 then multiply v1[j]*v2[n-1-j]. The algorithm works fine when I use c++ default sort() function. But if i use my own sorting function (selection sort), I get different output.
Further by observing the correct output file i noticed that if all the input numbers and positive my output is correct. However for negative numbers it is incorrect.
Here is the code of my sorting function:
`void sorted(long long int *a,int n)
{
long long int temp;
int minIndex;
for(int i=0;i<n;i++)
{
minIndex=i;
for(int j=i+1;j<n;j++)
{
if(a[i]>a[j])
minIndex=j;
}
if(minIndex!=i)
{
temp=a[minIndex];
a[minIndex]=a[i];
a[i]=temp;
}
}
}
`
Note that for this problem we have to use long long int because input numbers exceed int limits.
This is my main function:
#include <iostream>
#include<fstream>
using namespace std;
void sorted(long long int *a,int n);
int main()
{
ifstream inp("input.in");
int T;
inp>>T;
int n[T];
long long int *x[T], *y[T];
for(int i=0;i<T;i++)
{
inp>>n[i];
x[i]=new long long int[n[i]];
y[i]=new long long int[n[i]];
for(int j=0;j<n[i];j++)
inp>>x[i][j];
for(int j=0;j<n[i];j++)
inp>>y[i][j];
}
long long int minProduct[T];
ofstream out("output.txt");
for(int i=0;i<T;i++)
{
minProduct[i]=0;
sorted(x[i],n[i]);
sorted(y[i],n[i]);
for(int j=0;j<n[i];j++)
minProduct[i]=minProduct[i]+(y[i][n[i]-1-j]*x[i][j]);
out<<"Case #"<<i+1<<": "<<minProduct[i]<<endl;
}
return 0;
}
if i replace
sorted(x[i],n[i]);
sorted(y[i],n[i]);
with
sort(x[i],x[i]+n[i]);
sort(y[i],y[i]+n[i]);
and including algorithm header file, my output is correct.
What is the mistake in my sorting algorithm?
In the loop where you find the minimum index, you must compare the current item at index j with the item at the current index of the minimum item:
minIndex = i;
for (int j = i + 1; j < n; j++) {
if (a[minIndex] > a[j])
minIndex = j;
}
You always compare with the item at index i and hence don't account for updates on minIndex.

Why am I getting runtime error when I am trying to generate all prime numbers between m and n(m and n inclusive)?

Why am I getting runtime error when I am trying to generate all prime numbers between m and n(m and n inclusive)?
#include<iostream>
using namespace std;
typedef long long int ll;
int main()
{
ll n,m,i,ch,x,t;
cin>>t;
while(t--)
{
cin>>m>>n;
int a[n+1];
//a[n+1]={1};
for(i=2;i<=n;i++)
{
a[i]=1;
}
for(i=2;i<=n;i++)
{
if(a[i]==1)
{
x=2;
ch=0;
while((x*i)<=n)
{
if(a[x*i]==1)
{
a[x*i]=0;
ch++;
}
x++;
}
if(ch==0)
break;
}
}
for(i=m;i<=n;i++)
{
if(a[i]==1&&i!=1)
cout<<i<<"\n";
}
cout<<'\n';
}
return 0;
}
Ok, as from the link in your comment we have the following constraint
m and n (1 <= m <= n <= 1000000000, n-m<=100000)
So your algorithm will most probably fail in line
int a[n+1];
for large numbers n:
array of n = 1000000000 (1e9!) ints (4 bytes) needs 3.7GB of RAM!
So your approach doesn't work well for large numbers as it consumes too much RAM!
(I can reproduce it on local computer, just add cout message before and after definition of the array)
Edit
To make this algorithm work you should reserve memory on heap (instead of stack) and minimize size by int -> unsigned char at least:
...
while(t--)
{
cin>>m>>n;
unsigned char *a = new unsigned char[n+1];
...
delete[] a;
}

Newton's binomial - doesn't work for bigger numbers

I wrote a program which is supposed to print the value of Newton's binomial.
number - number of tests, t[i][0] - n, t[i][1] - k. It seems to be ok for small numbers n and k, but when I want to type bigger numbers it prints 0, 1 or small, negative integer. Basically I used long intead of int so it should work with bigger numbers. Could you explain why is that?
#include <iostream>
long fact(int x);
using namespace std;
int main()
{
int number;
cin>>number;
int t[number][2];
for(int i=0; i<number; i++)
{
cin>>t[i][0];
cin>>t[i][1];
if (t[i][0]<t[i][1]) return 0;
}
for(int i=0; i<number; i++)
{
cout<<fact(t[i][0])/(fact(t[i][0]-t[i][1])*fact(t[i][1]))<<endl;
}
return 0;
}
long fact(int x)
{
long factt=1;
for(int i=1; i<=x; i++)
{
factt=factt*i;
}
return factt;
}
#edit
Thanks for advice. I tried implementing this but it doesn't compute the binomial well. It prints 11 for n=4 and k=2. May you have a look at this?
#include <iostream>
long fact(int n, int k);
using namespace std;
int main()
{
int number;
cin>>number;
int t[number][2];
for(int i=0; i<number; i++)
{
cin>>t[i][0];
cin>>t[i][1];
if (t[i][0]<t[i][1]) return 0;
}
for(int i=0; i<number; i++)
{
cout<<fact(t[i][0],t[i][1])<<endl;
}
return 0;
}
long fact(int n, int k)
{
if(n==0 || n==k)
return 1;
else if(n>k)
return fact(n-1,k-1)+fact(n-1, k);
else
return 0;
}
Factorial grows really fast and even unsigned 64-bit integers overflow n! for n>20. The overflow free way to implement the binomial coefficient is to use this recursive definition:
binom(n, k) = binom(n-1, k-1) + binom(n-1, k)
This ensures that you get an overflow only when binom(n,k) is too large to fit in your integral type's size.
On Linux 32bit long is the same as int and fits into 32bit. On Linux 64bit long is 64bit long.
On Windows both 32bit and 64bit long is 32bits entity
You have to use long long to guaranteed to use 64bit, though it might be not enough to overcome overflow. Use recursive formula for binominal, if possible

finding the number of divisors don't know what is going wrong

I am coding to find the number of common divisors of two numbers n and k.
I am implementing it using the approach of finding the GCD g and then finding the number of divisors of the GCD.
However the code compiles but gives a not responding message on running :(
I have blown my head off on this.. can anyone please help in debugging..
Thanks in advance
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
vector<bool>p(1000002,true);
long int getgcd(long int a, long int b)
{ if(b == 0)
return a;
else
return getgcd(b, a % b);
}
void prime()
{ int i,j;
for(i=2;i<1000001;i++)
if(p[i])
for(j=i*i;j<1000001;j=j+i)
p[j]=false;
p[0]=false;
p[1]=false;
}
void divfind(long int a, long int b)
{
long int g;
g = getgcd(a,b);
int i,s,j=0,ans=1,num=0;
//short int fo[1000000];
s=(int) sqrt(g);
for(i=2;i<s+1;i++)
if(p[i])
{
while(g%i==0)
{g=g/i;
num++;
}
if(num)
ans*=++num;
num=0;
}
printf("%d\n",ans);
}
int main()
{
prime();
long int n;
int q;
scanf("%ld %d",&n,&q);
while(q--)
{
int t;
long int k;
scanf("%d%ld",&t,&k);
if(t==1)
divfind(n,k);
// else if(t==2)
// divi(n,k);
// else
// nodivi(n,k);
}
return 0;
}
You're running into integer overflows - i*i is only safe up to i=46340 (~2^15*sqrt(2)) with 32 bit integers, e.g:
i i*i
46339 2147302921
46340 2147395600
46341 -2147479015
46342 -2147386332
This leads to undefined behaviour.