When i run the source code on sample cases of their example it runs fine but when I submit the question It says runtime error.
Here is my Source code and link of the question.
Question link - https://www.codechef.com/SEPT21C/submit/MNDIGSM2
Below is the code.
#include <iostream>
#include <vector>
// #include <bits/stdc++.h>
using namespace std;
// #define fast ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int converter(int n , int b){
vector<int> vec;
int sum = 0;
while(n>0){
vec.push_back(n%b);
n = n / b;
}
int vecSize = vec.size();
for(int i = 0;i<vecSize;i++){
// cout<<
sum = sum + vec[i];
}
return sum;
}
int minVal(vector<int> arr , int len){
int min = arr[0], c = 0;
// if(arr)
for(int i = 1 ; i< len;i++){
if (arr[i] < min){
min = arr[i];
c = i;
}
}
return c;
}
int main() {
// your code goes here
// fast;
int test;
cin>>test;
while(test--){
int n ,r;
cin>>n>>r;
int l = 2;
// ll copy = l;
int arSize = (r-2)+1;
vector<int> arr(arSize);
for(int i = 0;i< arSize ;i++){
arr[i] = converter(n,l);
l++;
}
int tobe = minVal(arr , arSize);
cout<<tobe + 2<<endl;
}
return 0;
}
Maybe I do not understand the question fully. There is not enough information available.
It could be that the program slows down because the usage of the std::vector. First you calculate, then store the values and then iterate again over all values.
This is not necessary. You can do all calculations inline without the need for additional storage.
And, additionally, all these "contest" questions do not have the intention, to improve your programming skills.
Basically the language doesn't matter. The important thing is the algorithm. They want you to find a "good" algorithm.
Bruteforcing is nearly never a feasible solution. If you read about big numbers like 10^12, then you know already in advance that you will get a TLE with the brute force solution.
Regarding this horrible and non compliant C++ slang that is used on this "competetion" sides, please note that this is nearly never necessary. You have no time contraints to submit a solution. So, you could use also real C++ code.
Anyway. I corrected your code and added meaningful varibale names, comments and formatting. So, logically, the approach is the same, but it is readable.
Of course it may fail as well, because it is still brute forcing . . .
#include <iostream>
#include <limits>
constexpr unsigned long long BaseStart = 2ull;
int main() {
// Get number of test cases
unsigned int numberOfTestCases{};
std::cin >> numberOfTestCases;
// Work on all test cases
for (unsigned int testCase{}; testCase < numberOfTestCases; ++testCase) {
// Get the value to check and the upper limit for the base
unsigned long long valueToCheck{}, upperLimitBase{};
std::cin >> valueToCheck >> upperLimitBase;
// Here we will store the minimum sum to check
unsigned long long minimumsumOfDigits{std::numeric_limits<unsigned long long>::max()};
// Here we will store the result
unsigned long long minimumBase{};
for (unsigned long long base{BaseStart}; base <= upperLimitBase; ++base) {
// And this will be the running sumOfDigits
unsigned long long runningSumOfDigits{};
// get the digits of the value and calculate the running sum
unsigned long long value{valueToCheck};
while (value > 0) {
// Get digits via modulo division and add up
runningSumOfDigits += value % base;
value /= base;
}
// Get current minimum
if (runningSumOfDigits < minimumsumOfDigits) {
minimumsumOfDigits = runningSumOfDigits;
minimumBase = base;
}
}
std::cout << minimumBase << '\n';
}
return 0;
}
This code can of course be optimized further, but for this I would need more information . . .
program 1.
#include<iostream>
using namespace std;
int main()
{
int a[100000];
int *b=new int[1000000];
//for(int i=0;i<100000;i++)
//a[i]=0;
long long int sum=0;
const long long int x=1000000000000ll;
for(long long int i=2;i<1000000;i++)
{
if(b[i]==1)
continue;
for(long long int j=i*i;j<1000000;j+=i)
b[j]=1;
long long int k=((x-1)/i+1)*i-x;
//Sieve upto 10^12+10^5
for(;k<100000;k+=i)
a[k]=1;
}
for(int i=0;i<100000;i++)
{
if(a[i]!=1)
{
cout<<i+x<<" "<<i%1000<<endl;
sum=sum+i+x;
}
}
cout<<"sum="<<sum;
}
In the second program when I am printing some values before printing sum then it is changing the value of sum in the program. Can anybody tell me why is this happening?
program 2
#include<iostream>
using namespace std;
int main()
{
int a[100000];
int *b=new int[1000000];
//for(int i=0;i<100000;i++)
//a[i]=0;
long long int sum=0;
const long long int x=1000000000000ll;
for(long long int i=2;i<1000000;i++)
{
if(b[i]==1)
continue;
for(long long int j=i*i;j<1000000;j+=i)
b[j]=1;
long long int k=((x-1)/i+1)*i-x;
//Sieve upto 10^12+10^5
for(;k<100000;k+=i)
a[k]=1;
}
for(int i=0;i<100000;i++)
{
if(a[i]!=1)
{
sum=sum+i+x;
}
}
cout<<"sum="<<sum;
}
It looks like it is missing two values that I am going to sum.
basically sum is the total of all prime numbers between 10^12 to 10^12+10^5
When you create automatic array and dynamically allocated one in this code:
int a[100000];
int *b=new int[1000000];
they are unintialized. Later you read from b:
if(b[i]==1)
which leads to UB. You do assign some value to a in this code:
for(;k<100000;k+=i)
a[k]=1;
}
but it is not clear if all data is assigned. If not further reading from it leads to UB as well. You should initialize your data before using to eliminate UB and stop getting unpredictable results.
PS according to commented out code you tried to initialize a, but that would be not enough, b must be initialized as well.
Note: memory, allocated by new[] should be released by delete[], though that is not source of problem in your code. You better use std::vector which not only take care of memory allocation, but will properly initialize your data.
okay, I got the logic behind it, when I don't initialize array, it takes garbage values when might be 1 and 0 also, because was checking for
if(a[i] != 1)
{
sum = sum + i + x;
}
so due to the a[i] == 1 that been put by garbage value, I was getting wrong answer.
Run this to see 1 by garbage value
#include<iostream>
int main()
{
int a[100000];
for(int i = 0; i < 100000; i++)
std::cout << a[i] << std::endl;
}
But still don't have no idea, why the cout statement corrected it??
I was doing a problem named Sam and sub-strings on hackerrank which you can look by clicking on the corresponding link.
Here is my code. I am sure that the logic of my program is correct as it works for smaller values (and also the sample test cases). The problem is with modulus and I am not able to get how to use modulus in this program correctly. Can anyone please help me (if possible, please tell when/where to use modulus in the program without editing the rest of my program)?
My submission gives correct results for testcases 0,1,2,3,12 and incorrect results for the rest.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
long long int n;
cin >> n;
vector<long long int> v1;
while (n!=0){
v1.push_back(n%10);
n=n/10;
}
long long int x=1,s1=0,sum=0;
for (long long int i=v1.size()-1;i>=0;i--){
s1+=x*v1[i];
x++;
sum=(sum+(s1*(long long int)pow(10,i))%1000000007)%1000000007;
}
cout << sum << endl;
return 0;
}
I suggest you treat the number as text when playing with digits.
int main()
{
std::string number_as_text;
std::cin >> number_as_text;
long long sum = 0;
const std::string::size_type length = number_as_text.length();
for (unsigned int index = 0; index < length; ++index)
{
long long s1 = (number_as_text[index] - '0') * (index + 1);
sum = sum * 10 + s1;
}
return 0;
}
You'll have to figure out where to put the mod 1000000007 in your program, if you need to.
Also, I recommend placing error handling in the code, especially when reading in the number. The function std::isdigit looks helpful.
I am writing a simple code to calculate Fabonacci numbers as an exercise. The code works, but i don't get why. I have some special cases for n=1 and n=2 which is the place of the number in the sequence (the numbers are 0 and 1). However after those, the number is calculated in this loop.
while(n>LoopCount)
{
Fib_n=Fib_1+Fib_2;
Fib_2=Fib_1;
Fib_1=Fib_n;
LoopCount++;
}
Going in to the loop, Fib_1=0, Fib_2=0, and Fib_n=1. Why does not this loop just spit out 0 no matter what? The whole code is below.
#include <iostream>
using namespace std;
int main()
{
cout <<"Which number of the Fibonacci sequence do you want to calculate?" <<endl;
int n;
cin >>n;
cout <<endl;
int Fib_n;
int Fib_1;
int Fib_2;
int LoopCount=1;
if(n>1)
{
Fib_n=1;
LoopCount++;
while(n>LoopCount)
{
Fib_n=Fib_1+Fib_2;
Fib_2=Fib_1;
Fib_1=Fib_n;
LoopCount++;
}
}
cout <<Fib_n;
return 0;
}
int Fib_1;
int Fib_2;
were never initialized. Therefore, the first time you calculate Fib_n=Fib_1+Fib_2;, Fib_n will get the sum of two uninitialized variables.
I have modified your code so it would work.
#include <iostream>
using namespace std;
int main()
{
cout <<"Which number of the Fibonacci sequence do you want to calculate?" <<endl;
int n;
cin >> n;
cout << endl;
int Fib_1 = 1;
int Fib_2 = 1;
int count = 0;
while(n > count)
{
Fib_1 = Fib_1 + Fib_2;
Fib_2 = Fib_1 - Fib_2;
count++;
}
cout << Fib_1;
return 0;
}
Fib_1
You have that as an uninitalized variable, so you may get a garbage value for output.
Fib_2 = Fib_1
Next, you initialize Fib_2 with Fib_1, meaning they both share the same (random) value.
In debug mode, these are both initialized to 0, and adding them:
Fib_n=Fib_1+Fib_2;
makes the sum equal 0. In release mode, you can expect random values from the compiler. Here is more info on Uninitialized Variables.
a part of an assignment of mine is based on an array (its size is given by the user) which contains random numbers from 1 to 10^10. Then we have to find the k-th smaller number of the array. Here's what I tried:
#include <cstdlib>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <time.h>
using namespace std;
void swap(int *x,int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int choose_pivot(int i,int j )
{
return((i+j) /2);
}
// Print array
void printarr(int arr[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d\t",arr[i]);
}
// Find algorithm
int find1(int arr[],int left,int right,int k)
{
int i,j,pivot;
if (left==right)
return arr[left];
else
{
i=left;
j=right+1;
pivot= arr[left];
do
{
do {
i=i+1;
} while (arr[i]>=pivot);
do {
j =j-1;
} while (arr[j]<=pivot);
if (i<j)
swap(arr[i],arr[j]);
} while (j<=i);
}
swap(arr[left],arr[j]);
if (k==j)
return arr[j];
else if (k<j)
find1(arr,left,j-1,k);
else
find1(arr,j+1,right,k-j);
}
int main(int argc, char *argv[])
{
srand(time(NULL));
int n,i,fi,k;
printf("Give array's size:\n");
scanf("%d",&n);
int pin[n];
for (i=0;i<n;i++)
pin[i]=((rand()*rand()) % 1000000000) +1;
printf("Give k: \n");
scanf("%d",&k);
printf("The array contains the following numbers:\n\n");
printarr(pin,n);
fi=find1(pin,0,n-1,k);//find the k-th smallest number in the array
printf("The k-th smallest number is: %d",fi);
system("PAUSE");
}
As you can see 10^10 is a very big value, and I did something else to fill the array with the random numbers. Is it correct? Is there something else I could do?
And my second problem is on the find algorithm. It doesn't work. Could anyone help me with these? Thank you very much
long long get_big_rand()
{
long long result;
do {
result = (rand() & 0x3ff);
result <<= 12;
result |= (rand() & 0xfff);
result <<= 12;
result |= (rand() & 0xfff);
} while (++result > 10000000000ULL);
return result;
}
rand()*rand() is a lot different than a single rand(), it decreases the randomness and changes its distribution. See this question for a deeper explanation.
Also, an integer usually is 4 bytes. It can contain a value as big as 2^31 (2 billions and something) or 2^32 (4 billions and more) if it's unsigned. You can see the max number it can contain checking the INT_MAX macro defined in limits.h. 10^10 is 10 billions, it won't fit in an integer, you'll have to use a bigger type (long long usually is 64 bytes thus more than you need).
rand, also, returns numbers up to RAND_MAX, and since it returns an int, it won't bigger than INT_MAX. You should use some other way to generate a number as big as 10^10.
If you don't care about randomness and random number distributions you could sum n random numbers (obtained by rand) so that n=10^10 / RAND_MAX.
If you take a closer look at 1010 you will notice that it's quite a round limit. My take on this would be to generate each number, one digit at a time and ignoring insignificant zeroes. At this point you would have a number between 0 and 1010-1 inclusive. All you're left with doing is adding a 1.
As for random()*random(), that is the exact topic of this other question.
Alin
Problem #1, an int will only hold a number of size 2^31 in size. You'll need a slightly bigger alternative for your pin array.
Also, multiplying your two random numbers together really doesn't do much - except perhaps make the number less random.
Next, you can't create an array on the stack dynamically with the user's input. That will require a new solution to make alloc an array for you.
rand()*rand() isn't going to do anything for you. It doesn't scale the way you think it does, and it does change the distribuon. In fact
double norm_rand(){
double r=0;
for(unsigned i=0;i!=12;++i)
r+=rand()/static_cast<double>(RAND_MAX);
return (r/12)-6;
}
is a common way to simulate a normal distribution with mean 0 and variance 1;
The best way to to get large random numbers is using a random number device, like /dev/urandom or RtlGenRandom.
i.e.
typedef unsigned long long big_type;
std::vector<double> rnums;
std::vector<big_type> buf(numtoread);
std::ifstream rnds("/dev/urandom");
rnds.read(reinterpret_cast<char*>(&buf[0],buf.size()*sizeof(big_type));
std::transform(buf.begin(),buf.end(),std::back_inserter(rnums),
[](big_type const& i){
return (i*100000000000.)/(std::numeric_limits<big_type>::max());
});
At the risk of doing your homework for you, an entirely different approach is to use the libraries that come with C++.
#include <cassert>
#include <sstream>
#ifndef _MSC_VER //then assume Linux
#include <tr1/random>
#else
#include <random>
#endif
#include <boost/lexical_cast.hpp>
#include <algorithm>
#include <iterator>
#include <iostream>
int main(int argc, char** argv)
{
assert(argc==3);
unsigned const numentries=boost::lexical_cast<unsigned>(argv[1]);
unsigned const k=boost::lexical_cast<unsigned>(argv[2]);
std::cout<<" finding "<<k<<"th of "<< numentries<<" entries\n";
assert(k<=numentries);
std::vector<double> nums(numentries);
std::tr1::uniform_real<> rng(0.,10000000000.);
std::tr1::minstd_rand generator(42u);
std::tr1::variate_generator<std::tr1::minstd_rand, std::tr1::uniform_real<> >
uni(generator, rng);
std::generate_n(nums.begin(),nums.size(),uni);
std::cout<<" Generated:\t ";
std::copy(nums.begin(),nums.end(),std::ostream_iterator<double>(std::cout,"\t"));
std::sort(nums.begin(),nums.end());
std::cout<<"\n The "<<k<<"th smallest entry is "<<nums[k]<<"\n";
return 0;
}
(If you are in class at the level of just asking for making an array of rand numbers and you hand that in, they'll probably fail you)
What I do in practice is to combine the two approaches. This is used in place of the linear conguentual rng used above (the minstd_rand):
template<typename bigtype=unsigned>
struct randeng {
typedef bigtype result_type;
randeng(unsigned x) :
m_samplesrequired(x), m_samples(x), m_lastused() {
std::ifstream rand;
rand.open("/dev/urandom");
assert(rand);
rand.read(reinterpret_cast<char*> (&*(m_samples.begin())),
m_samplesrequired * sizeof(unsigned));
}
result_type operator()() const {
assert(m_lastused<m_samplesrequired);
return m_samples[m_lastused++];
}
result_type max() const {
return std::numeric_limits<result_type>::max();
}
result_type min() const {
return 0;
}
unsigned m_samplesrequired;
std::vector<result_type> m_samples;
mutable unsigned m_lastused;
};
This always seems to give much better results.
you forgot your return statements. at the end of find1 you should be doing:
if (k==j)
return arr[j];
else if (k<j)
return find1(arr,left,j-1,k);
else
return find1(arr,j+1,right,k-j);
}