Can't increase range of numbers in a program in C++ - c++

Here is the question:
Comparing two numbers written in index form like 2^11 and 3^7 is not difficult, as any calculator would confirm that 2^11=2048<3^7=2187.
However, confirming that 632382^518061>519432^525806 would be much more difficult, as both numbers contain over three million digits.
You are given N base exponent pairs, each forming a large number you have to find the Kth smallest number of them. K is 1−indexed.
Input Format
First line containts an integer N, number of base exponent pairs. Followed by N lines each have two space separated integers B and E, representing base and exponent.
Last line contains an integer K, where K<=N
Constraints
1≤N≤105
1≤K≤N
1≤B≤109
1≤E≤109
No two numbers are equal.
Here is my code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N,i = 0,k,j=0,x,m;
long long int *arr,*arr2,*arr3;
cin >> N;
arr = (long long int *)malloc(sizeof(long long int)*2*N);
arr2 = (long long int *)calloc(N,sizeof(long long int));
arr3 = (long long int *)calloc(N,sizeof(long long int));
x = 2*N;
while(x>0)
{
cin >> arr[i];
i++;
x--;
}
cin >> k;
for(i=0;i<2*N;i+=2)
{
arr2[j] = pow(arr[i],arr[i+1]);
j++;
}
arr3 = arr2;
sort(arr2,arr2+N);
for(i=0;i<N;i++)
{
if(arr3[i] == arr2[k-1])
{
m = i;
break;
}
}
cout << arr[2*m] << " " << arr[2*m + 1];
return 0;
}
The program works for small numbers only, can't make it work for large numbers. what to do?

Maybe you are generating an overflow on the big numbers. You could consider using a multiprecision arithmetic library such as https://gmplib.org/. I haven't used this library myself.
Have a look at this post How to detect integer overflow? on how to detect integer overflow.

From your choosing of long long int type I guess you calculated the a^b of the numbers in order to sort them, which leads to very big numbers and may lead to overflow.
Note that in order to sort the numbers there is no need for this calculation, for knowing if a^b > d^c it is sufficient to check log(a^b) > log(c^d) and therefore b*log(a) > d*log(c).
And it's better to use a struct or class to create a data structure for this big numbers.
This is the code for it:
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
struct BigNumber{
int base;
int exponent;
};
int Compare(BigNumber x, BigNumber y);
void Sort(BigNumber* arr, int N);
int main() {
int N,i = 0,k;
BigNumber *numbers;
cout<<"\nEnter N:";
cin >> N;
numbers = (BigNumber *)calloc(N,sizeof(BigNumber));
for(i=0; i<N; i++)
{
cout<<"\nEnter base and exponent for number "<<i<<":";
cin >> numbers[i].base>>numbers[i].exponent;
}
cout<<"\nEnter K:";
cin >> k;
Sort(numbers,N);
cout << "Kth number is :" << numbers[k].base << "^" << numbers[k].exponent;
return 0;
}
void Sort(BigNumber* arr, int N){
for(int i=0; i< N; i++ ){
for(int j=0; j< N; j++){
if(Compare(arr[i], arr[j])<0){
BigNumber temp = arr[j];
arr[j] = arr[i];
arr[i] = arr[j];
}
}
}
}
int Compare(BigNumber x, BigNumber y){
double X = x.exponent * log10(x.base);
double Y = y.exponent * log10(x.base);
return X == Y? 0: X > Y ? 1: -1;
}

I changed the code a little. Only problem I was having was I was calculating the exponent rather than comparing log of exponent.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N,i = 0,k,j=0,x,m;
int *arr;
double *arr2,*arr3;
cin >> N;
arr = (int *)malloc(sizeof(int)*2*N);
arr2 = (double *)calloc(N,sizeof(double));
arr3 = (double *)calloc(N,sizeof(double));
x = 2*N;
while(x>0)
{
cin >> arr[i];
i++;
x--;
}
cin >> k;
for(i=0;i<2*N;i+=2)
{
arr2[j] = arr[i+1]*log10(arr[i]);
j++;
}
for (i = 0; i < N; i++) {
arr3[i] = arr2[i];
}
sort(arr2,arr2+N);
for(i=0;i<N;i++)
{
if(arr3[i] == arr2[k-1])
{
m = i;
break;
}
}
cout << arr[2*m] << " " << arr[2*m + 1];
return 0;
}

Related

How to find missing number in array

#include <iostream>
#include <algorithm>
using std::cin;
using std::cout;
using std::endl;
using std::sort;
int main()
{
int x = 0;
int n; // Enter Size of 2 array
cin >> n; // enter 5
long long *ptr1 = new long long[n - 1]; // size of array must be less than 5 by one n-1
for (int x = 0; x < n - 1; x++)
{
cin >> ptr1[x];
}
sort(ptr1, ptr1 + (n - 1));
for (int z = 1; z < n; z++)
{
if (z != ptr1[x])
{
cout << z;
break;
}
x++;
}
return 0;
}
You're given all positive integers from 1,2,…,n except one integer. Find the missing integer.
Input
The first line of input contains an integer n (2≤n≤2×105).
The second line of input contains n−1 distinct integers from 1 to n (inclusive).
Output
Print the missing integer.
when i try to sumbit this code i get wrong in test 10 but i don't know why! and he didn't show the test so what is wrong?
I have a three-fold answer:
This program leaks memory
You included <algorithm> please use it. (Look on cppreference)
Spoilers vector, iota, mismatch
Also, you don't reset x before the second loop.
That's never going to work unless the missing integer is the last of the array, and not equal to 1
// for (... z)
if (z != ptr1[x] /* Here */) {
// print 1, end loop OR invoke undefined behavior
}
x++; // Now x is equal to (n - 1)
There are some problems with your code:
long long *ptr1 = new long long[n - 1];
You call new, without delete. This will create a memory leak.
You haven't reinitialized x, so any access to ptr1[x] is out-of-bounds.
Slove all of that, and your code will look like:
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
int n;
cin >> n;
std::vector<int> vec(n-1); // std::vector instead
for (int x = 0; x < n - 1; x++)
{
std::cin >> vec[x];
}
std::sort(vec.begin(), vec.end());
int x = 0; // use another variable instead of reused the old one.
for (int z = 1; z < n; z++)
{
if (z != vec[x])
{
std::cout << z;
break;
}
x++;
}
return 0;
}
But, this isn't the best approach anyway. As #molbdnilo suggest:
#include <iostream>
int main()
{
int n;
std::cin >> n;
int sum{};
for (int i = 0; i < n - 1; ++i)
{
int tmp;
std::cin >> tmp;
sum += tmp;
}
std::cout << (n + 1) * n / 2 - sum;
}
You can solve this in a more straightforward way if you subtract the numbers that were entered from the expected sum of all numbers 1, 2, ..., n (see comments by #molbdnilo, #Aconcagua and #marcus-müller):
#include <iostream>
int main() {
std::size_t n;
std::cin >> n;
std::size_t sum{ n*(n + 1)/2 };
for (std::size_t idx = 1; idx != n; ++idx) {
std::size_t thisNumber;
std::cin >> thisNumber;
sum -= thisNumber;
}
std::cout << "Missing number: " << sum << std::endl;
}
Building blocks:
The expected sum: int expected_sum = n * (n + 1) / 2;
The sum of all integers fed to the test after you've read n:
#include <iterator> // istream_iterator
#include <numeric> // accumulate
int sum = std::accumulate(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>{}, 0);
Now, expected_sum - sum should give you the missing value.

why is the answer not showing up?

I am doing a code in c++ where I am supposed to be finding the series and I build the function for the series myself yet and I call the function I don't find my answer
here is my code
#include <iostream>
#include <cmath>
using namespace std;
double harmonicSeries(int n);
int main() {
int n;
cout << "Enter n" << endl;
cin >> n;
harmonicSeries(n);
}
double harmonicSeries(int n) {
for (int i = 1; i <= n; i++) {
float s;
float sum = 0.0;
s = 1 / n;
sum += s;
return sum;
}
}
I will be thankful for any help
See I have made the changes in your code,this works fine in this finding numbers and adding to get their sum.You should use return outside the function and basically harmonic series is of form 1/n which can be any float number or double number so I use s as double and i has float(which by this).
s=1/i(double=1/float,gets converted to double)
#include <iostream>
#include <cmath>
using namespace std;
double harmonicSeries(int n);
int main() {
int n;
cout << "Enter n" << endl;
cin >> n;
cout<<harmonicSeries(n);
}
double harmonicSeries(int n) {
double sum=0.00;
double s;
for (float i = 1; i <= n; i++) {
s = 1 / i;
sum += s;
}
return sum;
}
If you find anything wrong do ask for sure:)

Stack Overflow for Fractional Knapsack

I am fairly new to C++. I have implemented the fractional knapsack problem in c++ for the course "Algorithmic Toolbox" on Coursera:
#include <iostream>
#include <iomanip>
using namespace std;
int get_max_index(double A[], double B[],int l)
{
/*
int A = array of value
int B = array of weights
int l = length of the array
*/
int p,Max{0};
for(int j=0;j<l;j++)
{
if((A[j]/B[j]) > Max){Max = A[j]/B[j];p = j;}
}
return p;
}
int main()
{
int n,W,q,Max{0},W1{0};
cin >> n >> W;
double values[n],weights[n],loot{0};
for(int i=0;i<n;i++)
{
cin >> values[i] >> weights[i];
}
for(int j=0;j<n;j++)
{
if(W==0){break;}
else
{
q = get_max_index(values,weights,n);
if(weights[q] <= W){W1 = weights[q];}
else{W1 = W;}
loot += W1 * (values[q]/weights[q]);
W -= W1;
weights[q] -= W1;
if(weights[q] == 0){values[q] = 0;}
}
}
cout << setprecision(4) << fixed;
cout << loot << endl;
}
After submitting this code I got a stack overflow error (unknown signal 11). Please help me understand why this happens and solution to this problem.
EDIT :
I have changed the code. I am not using the get_max_index function with dynamically sized arrays. Here is the new code:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
long long int n,W,q,p,Max{0},W1{0};
cin >> n >> W;
long double values[n],weights[n],loot{0},VPU[n];
for(long long int i=0;i<n;i++)
{
cin >> values[i] >> weights[i];
VPU[i] = values[i] / weights[i];
}
for(long long int j=0;j<n;j++)
{
if(W==0){break;}
else
{
for(long long int k=0;k<n;k++)
{
if(VPU[k] > Max){Max = VPU[k];p=k;}
}
Max = 0;
q = p;
if(weights[q] <= W){W1 = weights[q];}
else{W1 = W;}
loot += W1 * (values[q]/weights[q]);
W -= W1;
weights[q] -= W1;
if(weights[q] == 0){VPU[q] = 0;}
}
}
cout << setprecision(4) << fixed;
cout << loot << endl;
}
C++ standard doesn't allow variable-length arrays. So that it is not legal(even though some compilers might support it) to create a static array(allocated in stack) double values[n],weights[n]... with a size that is not known in compile time. The stack overflow error is most probably because of that(n is not known at compile time and a junk value that breaks your stack might be read). Instead try allocating them in heap with new double[n] syntax. Don't forget to free the array at the end.

Non-Divisible Subset - Hackerrank

I am trying to solve the Non-Divisible Subset problem from Hackerrank (https://www.hackerrank.com/challenges/non-divisible-subset). I am trying to use the idea that if the sum of a and b is divisible by k, then a%k+b%k = k, however, it's not working very well.
Here is what I've written so far:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
int k;
cin >> n;
cin >> k;
int j;
vector<int>numbers;
vector<int>remainders;
for(int i = 0; i < n; i++) {
int z;
cin >> z;
numbers.push_back(z);
}
for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++) {
j = *it % k;
remainders.push_back(j);
}
for(vector<int>::iterator it2 = remainders.begin(); it2 != remainders.end(); it2++) {
int remainderCount = 0;
int otherRemainderCount = 0;
otherRemainderCount = std::count(remainders.begin(), remainders.end(), k-*it2);
remainderCount = std::count(remainders.begin(), remainders.end(), *it2);
if (remainderCount > otherRemainderCount) {
theChosenOne = *it2;
} else if (otherRemainderCount > remainderCount) {
theChosenOne = k-*it2;
}
cout << theChosenOne << endl;
}
return 0;
}
I created a vector for the remainders and I am using the std::cout function to find out which remainder appears more in the vector. If K would be 5, *it2 = 4, and k-*it2 = 1. If *it2 appears more times, then I would choose *it2. Otherwise, I would choose k-*it2.
Your solution looks to be on the right track, but there is some change that is needed.
You basically need to hash the numbers in the array to proper location.
Have an array rem[k] initialised to 0.
Iterate over the n numbers in the array, and do the following:
rem[array[i]%k]++;
Now you have to deal with only the rem[] array, to find the maximum subset. The rem array has size of maximum k<=100. Make use of the small size of rem[] array to find the solution efficiently.
Edit: Adding the code for you.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n,i,k;
cin>>n>>k;
int arr[n];
int rem[k]={0};
for(i=0;i<n;i++)
{
cin>>arr[i];
}
for(i=0;i<n;i++)
{
rem[arr[i]%k]++;
}
int count = 0;
for(i=1;i<=k/2;i++)
{
count = count + max(rem[i],rem[k-i]);
}
count = count + (rem[0]>0?1:0);
if(k%2==0)
{
count = count - rem[k/2];
if(rem[k/2]>0)
count = count + 1;
}
cout<<count;
return 0;
}
After you have found out the contents of the rem[] array, its time to find the maximum subset. If you select rem[1] then you cannot select rem[k-1] as any two numbers, one from rem[1] and another from rem[k-1] can be summed together which will be divisible by k that we don't want. So we find whichever is maximum out of rem[i] and rem[k-i] and add it to the count
My code uses the above logic..
Hope it helps!!!
int main() {
int n,k;
cin>>n>>k;
vector <int> a(n);
vector <int> r(k,0);
for(int i=0;i<n;i++)
{
cin>>a[i];
r[a[i]%k]++;
}
int ctr=min(1,r[0]);
for(int a=1;a<(k/2+1);a++)
{
if(a!=k-a)
ctr+=max(r[a],r[k-a]);
}
if(k%2==0&&r[k/2]!=0)
ctr++;
cout<<ctr;
return 0;
}
This seemed to work
#include <stdio.h>
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int main() {
int n, k, a, total = 0;
scanf("%d %d", &n, &k);
int mods[k];
for (int i = 0; i < k; i++)
mods[i] = 0;
while (n--) {
scanf("%d", &a);
mods[a % k]++;
}
// can only have 1 value congruent to 0 mod k
total += min(1, mods[0]);
// if even, can only have 1 value congruent to k/2 mod k
if (k % 2 == 0)
total += min(1, mods[k / 2]);
// for all others, pick max of those k and n-k mod k
for (int d = 1; d < (k + 1) / 2; d++) { // for all others,
total += max(mods[d], mods[k - d]);
}
printf("%d", total);
return 0;
}

creating an upwards series in c++

Screenshot of my code
Hey, I have just started learning C++ and I am trying to get it to sum the series:
K+N−1∑n=K [-1^(n)/(n+1)2]
I have managed to get it to tell me the nth term previously, but now I would like to for each term in the series, starting with the kth and going in sequence to the last (k+n-1st), add this term to the running sum.
I need to use a function direct_up() which uses the function term(). I defined initially and test it in the main.
I know I am missing something and am a bit confused about how to use the functions and that I may have made a few mistakes. So I would be very grateful for some advice or help. I have attached a picture of what I have done so far, as well as typed it below.
using namespace std;
double term(int n) {
double y;
if(n%2==1) {
y = -1.0/((n+1.0)*(n+1.0));
} else {
y = 1.0/((n+1.0)*(n+1.0));
}
return y;
}
double direct_up(int k, int n) {
int startingnumber = k;
for (int i = startingnumber; i <= k+n; i++) {
cout << n << term(n) << endl;
}
return n;
}
int main() {
double n;
int k;
cout.precision(16);
cout << "enter number of terms";
cin >> n;
cout << "enter a value for k";
cin >> k;
cout << "here is the value" << direct_up(k,n);
return 0;
}
This is what you want to do:
double direct_up(int k, int n)
{
int startingnumber = k;
double sum = 0;
for (int i = startingnumber; i <= k+n; i++) {
sum += term(i);
}
return sum;
}
Here's how to do it without keeping your own running sum as you asked in your comment:
#include <vector>
#include <numeric>
double direct_up(int k, int n)
{
int startingnumber = k;
std::vector<double> terms;
for (int i = startingnumber; i <= k+n; i++) {
terms.push_back(term(i));
}
return accumulate(terms.begin(), terms.end(), 0.0);
}