c++ noob coder questions - c++

using namespace std;
int main()
{
cout << "\n\n Find the perfect numbers between 1 and 500:\n";
cout << "------------------------------------------------\n";
int i = 1, u = 1, sum = 0;
cout << "\n The perfect numbers between 1 to 500 are: \n";
while (i <= 500)
{
while (u <= 500)
{
if (u < i)
{
if (i % u == 0)
sum = sum + u;
}
u++;
}
if (sum == i) {
cout << i << " " << "\n";
}
i++;
u = 1;
sum = 0;
}
}
why we added u=1 and sum=o in the last two lines? Can somebody help me with this? I am not able to comprehend the logic behind changing the logic at the end.

Those lines are for re-initializing the variables.
The code you have posted is for finding the perfect numbers which are just numbers that equals the sum of its own proper divisors. eg: 6, the proper divisors are 1, 2, 3. sum of 1 + 2 + 3 = 6. So, 6 is a perfect number.
The first while loop
while (i <= 500)
is for going through the numbers between 1 and 500 one by one
and the second while loop
while (u <= 500)
is for checking the divisors for a particular i. At first the loop will run for i = 1, the second while loop runs for 500 times and check the divisors of 1. Now, for i = 2, we have to check the divisors again from u = 1 right, so the re-initialization is done after the second while loop.
actually you should change the second loop to
while (u < i)
or even better
while (u <= (i / 2))

Related

Unable to figure out why my solution for Codechef problem MXEVNSUB is failing

Question: https://www.codechef.com/problems/MXEVNSUB
The following is my understanding of the problem.
This problem is asking for the maximum length of its contiguous subsequence with an even sum.
For
N = 1, Sum = 1 (odd sum but we need not bother about N = 1, since 2 <= N <= 10000)
N = 2, Sum = 3 (odd sum)
N = 3, Sum = 6 (even sum)
N = 4, Sum = 10 (even sum)
N = 5, Sum = 15 (odd sum)
N = 6, Sum = 21 (odd sum)
.
.
.
N = k- 1, Sum = ((k - 1) * k) / 2 (I assume it’s sum is odd)
N = k, Sum = (k * (k + 1)) / 2 (Worst case, this one might be odd too)
So I used the following logic in my code.
If the sum of numbers up to N is even, I can simply print the value of N and break out of the loop, else I reduce N by 1 and repeat the process.
The inner while loop in my code is a O(1) operation since in the worst case it runs 3 times (2 times for odd sum and the third time when sum is even)
Here is the code which is giving me WA
#include<bits/stdc++.h>
using namespace std;
int main(){
int tc; cin >> tc;
while(tc--){
int n; cin >> n;
if(n == 2) {
cout<<-1<<endl;
continue;
}
while(n){
if( ( (n * (n + 1) ) / 2 ) % 2 == 0){
cout << n << endl;
break;
}
n--;
}
}
}
I tried to submit the solution and it works for the sample test cases but is giving me Wrong Answer on submitting.

C++: Dynamic programming, given 3 possible operations

Question:
So the question goes like this: I have N numbers. For each number X in the array of length N, I can perform 3 operations: 1. If X is a multiple of 2, divide X by 2. 2. If X is a multiple of 3, divide it by 3. 3. Subtract 1 from X. Find the minimum number of operations to make X = 0. This code is meant to be done using dynamic programming...
Input:
line 1: N line 2: Array X of N numbers
Output:
line 1: Number of operations to reduce X1 to 0. ... line N: Number of operations to reduce XN to 0.
So how should I go about doing this?
Code:
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
cin >> N;
for (int i = 0; i < N; i++){
int A, count = 0;
cin >> A;
while (A > 0){
if (A%2 == 0){
A /= 2;
count++;
}
else if (A%3 == 0){
A /= 3;
count++;
}
else{
A--;
count++;
}
}
cout << count << "\n";
}
}
This code which I currently have in mind does not work for some cases(meaning I do not output the desired solution, and that the code is a working code), say Xi = 10. My code does 10/2, then -1, then /2, then /2 then -1, so it is 5 operations. However, the optimal is 10 -1, /3, /3 again, then -1, which is 4 operations. Anyone has any idea how I should code my solution to this problem? Thanks! Any help is appreciated!
You said dynamic programming:
std::vector<int> v{0};
for (int i = 1; i != N + 1; ++i) {
v.push_back(v.back() + 1);
if (i % 2 == 0) {
v.back() = std::min(v.back(), v[i / 2] + 1);
}
if (i % 3 == 0) {
v.back() = std::min(v.back(), v[i / 3] + 1);
}
}
return v.back();

Print divisors in order using theta(n) efficiency

I'm struggling to implement this correctly. I want to create a function that determines all of the divisors of the user input userNum and outputs them to the user. When userNum = 16 i'm getting the output 1 16 2 8. I didn't expect the order to be correct, but i'm missing 4 and am struggling to figure out why. Any thoughts? I'm trying to do this in theta(sqrt(num)) efficiency.
void PrintDivisors(int num);
int main()
{
int userNum;
//Request user number
cout << "Please input a positive integer >=2:" << endl;
cin >> userNum;
PrintDivisors(userNum);
return 0;
}
void PrintDivisors(int num)
{
int divisorCounter;
for (divisorCounter = 1; divisorCounter < sqrt(num); divisorCounter++)
{
if (num % divisorCounter == 0 && num / divisorCounter != divisorCounter)
cout << divisorCounter << endl << num / divisorCounter << endl;
else if (num % divisorCounter == 0 && num / divisorCounter == divisorCounter)
cout << divisorCounter << endl;
}
}
Update: I have all the numbers printing, but still trying to determine how to print them in order while remaining within theta sqrt(n) efficiency
Change loop termination condition operation to <=, now you will observe 4.
Get rid of sqrt function call. Better use this loop
for (divisorCounter = 1; divisorCounter * divisorCounter <= num; divisorCounter++)
Make sure to check your edge conditions carefully.
What is sqrt(num)?
What is the largest divisorCounter that will pass the test in the for loop?
Would 4 pass the test?
I think if you look carefully at that line with these three questions in mind you will squash the bug.
For making it run in sqrt(n) time complexity:
For any n = a X b. either a<=sqrt(n) or b<=sqrt(n).
So if you can find all divisors in range [1,sqrt(n)] you can find other divisors greater than sqrt(n)
You can use a for loop to traverse numbers in range 1 to sqrt(n) and find all the divisors less than sqrt(n), which at the same time you can also use to find other numbers greater than(or equal to) sqrt(n).
Suppose a number i < sqrt(n) is divisor or n. In that case the number k = n/i will also be divisor of n. But bigger than sqrt(n).
For printing numbers in sorted order:
During finding divisors in range [1,sqrt(n)] print only divisor in range [1,sqrt(n)] You can use an array/vector to store numbers in range [sqrt(n),n] and print them after the for loop ends. Here is a sample code
vector<int> otherNums;
for(i=1;i*i<n;i++) {
if(num%i==0){
cout<<i<<endl;
otherNums.push_back(n/i);
}
}
if(i*i == n) otherNums.push_back(i);
for(i=(int)v.size() - 1 ;i>=0;i--)
cout<<otherNums[i]<<endl;
This is the solution I ended up using, which saves space complexity too. I was struggling to think of effective ways to loop over the solution in ascending order, but this one runs very fast and is nicer than appending to a vector or array or some weird string concatenation.
void printDivisors(int num)
{
for (int k = 1; k*k < num; k++)
{
if (num % k == 0)
cout << k << " ";
}
for (int d = sqrt(num); d >= 1; d--)
{
if (num % d == 0)
cout << num / d << " ";
}
cout << endl;
}

basic nestled loop calculate prime numbers between 1 - 239, inclusive

I am working on a program in which I must print out the number of primes, including 1 and 239, from 1 - 239 ( I know one and or two may not be prime numbers, but we will consider them as such for this program) It must be a pretty simple program because we have only gone over some basics. So far my code is as such, which seems like decent logical flow to me, but doesnt produce output.
#include <iostream>
using namespace std;
int main()
{
int x;
int n = 1;
int y = 1;
int i = 0;
while (n<=239)
{x = n % y;
if (x = 0)
i++;
if (y < n)
y++;
n++;
while (i == 2)
cout << n;
}
return 0;
}
The way I want this to work is to take n, as long as n is 239 or less, and preform modulus division with every number from 1 leading up to n. Every time a number y goes evenly into n, a counter will be increased by 1. if the counter is equal to 2, then the number is prime and we print it to the screen. Any help would be so greatly appreciated. Thanks
std::cout << std::to_string(2) << std::endl;
for (unsigned int i = 3; i<240; i += 2) {
unsigned int j = 3;
int sq = sqrt(i);
for (; j <= sq; j += 2) if (!(i%j)) break;
if (j>sq) std::cout << std::to_string(i) << std::endl;
}
first of all, the prime definition: A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
so you can skip all the even numbers (and hence ... i+=2).
Moreover no point to try to divide for a number greater than sqrt(i), because then it will have a divisor less than sqrt(i) and the code finds that and move to the next number.
Considering only odd numbers, means that we can skip even numbers as divisors (hence ... j+=2).
In your code there are clearly beginner errors, like (x = 0) instead of x==0. but also the logic doesn't convince. I agree with #NathanOliver, you need to learn to use a debugger to find all the errors. For the rest, good luck with the studies.
lets start with common errors:
first you want to take input from user using cin
cin>>n; // write it before starting your while loop
then,
if (x = 0)
should be:
if (x == 0)
change your second while loop to:
while (i == 2){
cout << n;
i++;
}

Implementing a prime number counter

For some reason, my last prime(int prime) isn't showing up at the end. Any clue ?
fyi: primeEval stands for a flag, if the loop ends && primeEval==2, the number is actually a prime number. qty stands for quantity of primes counted.
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}
New Answer:
With the change in your code you will now loop through all number. The problem with it now is that once you find a non prime number you will never reset primeEval and because of that you will never capture another prime number If you change your code to the following it will work
int main()
{
long primeEval = 0, prime = 0, qtyprime = 0;
time_t timerr = (time(NULL) + 10);
for (int i = 2; time(NULL) != timerr; i++) {
for (int j = 1; j <= i; j++) {
if ((i%j) == 0){
primeEval++; // incmrent factor
}
// if we are at the end and have 2 factors then we are prime
if (i == j && primeEval == 2) {
qtyprime++;
prime = i;
primeEval = 0; // Resets for the next number 'i'
}
// if we reach the end with more than 2 factors reset and go to the next number
if (i == j && primeEval > 2) {
primeEval = 0; // Resets for the next number 'i'
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
cin.get();
return 0;
}
I would also suggest you look at Which is the fastest algorithm to find prime numbers? to find some more efficient ways to get prime numbers.
Old Answer:
In your code you have:
for (int i = 2; time(NULL)!=timerr; i=+2)
So when you start checking from primes you start with 2 which is prime. Then you increment i by 2 so the next number you check is 4 which is an even number. All even numbers are not prime except for 2. Since you are always adding 2 you will always have an even number so the only prime number you will find is 2.
You have different issues:
for (int i = 2; time(NULL)!=timerr; i=+2) {
Here the syntax is just wrong: it must be i+=2, not i=+2, otherwise you will keep setting i to +2 and testing whether 2 is prime.
Then, as others have pointed out, why are you increasing i by 2? If you want to optimize the search, you should increase j by 2, not i! And j should in any case start from 2 (or, given your approach, from 1), and then you should try j = 3 and then you can increase j by 2 without the risk of skipping some important divisors.
Then, you reset primeEval to 0 only if you find a prime. If you test a number i that is not prime, primeEval stays at 2 and you'll never get into the block again.
So the final code could be:
#include <iostream>
using namespace std;
int main(){
long primeEval=0,prime=0,qtyprime=0;
time_t timerr=(time(NULL)+10);
for (int i = 2; time(NULL)!=timerr; i++) {
primeEval=0;
for (int j = 1; j <= i; j++) {
if((i%j)==0 && primeEval<2){
primeEval++;
if (i==j && primeEval==2) {
qtyprime++;
prime=i;
primeEval=0; // Resets for the next number 'i'
}
}
}
}
cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}