I need better understanding on for loops - c++

can someone explain me how this for loop works (Line 9 in code below), and also if you can show me a simple example with it can be very helpfull, thank you anyways!
1 #include <iostream>
2 #include <cstdlib>
3
4 using namespace std;
5 int main(){
6 int n, a , b , ma=0,mb=1000000001;
7 cin >> n ;
8 cin >> a;
9 for( n--; n ; --n ){
10 cin >> b;
11 if(abs(a-b) < abs(ma-mb))
12 ma=a , mb=b;
13 else
14 if(abs(a-b) == abs(ma-mb) && ma+mb > a+b)
15 ma=a , mb=b;
16 a = b;
17 }
18 cout << ma << " " << mb;
19 return 0;
20 }

A for loop is simply another way to write a while loop. So this:
for( n--; n ; --n ){
...
}
is the same as this:
n--;
while(n) {
...
--n;
}
Which, in this specific case, is easier to read. First it decrements n, then does the loop, decrementing n again at the end of each loop, until that decrement causes n to evaluate to false by becoming 0.

This code smells a lot. If you give to n the value 10,it gives
9 (first time into loop, exectues n--)
every other iteration it executes --n till when n!=0 (which is the condition n

A for loop works the following way:
It runs for a certain number of times. We signify this with a condition. It has a start and an increment:
for (start ; condition ; increment )
{
// loop body
}
For loops and all loops are very useful when you want to perform repetitive tasks.
Lets say that you want to make a game and this game will have 3 rounds. Each one of those rounds can be implemented as an iteration of a for loop. It will look like this:
for(int round = 0; round < 3; ++round) {
// game round logic
}
In the above loop we start at 0. Once we reach 3, we would have already executed the for-loop 3 times. After each iteration of the for loop ++round gets executed, this increments the variable round by 1. We can increment it by a different value by doing: round+=2 or round*=2 etc.

Related

what's wrong with my code [ Dfs , Dynamic programming ]

i tried to solve this problem with dfs and dynamic programming . then
i submit my code to my school grader but the answer is wrong .
am i implement something wrong with dfs .
what's wrong with my code.
PS.sorry for my bad english
The problem :
given a random number there's 2 different way you can do with this
number
1.divide it by 3 (it has to be divisible)
2.multiply it by 2
given n number find the original order before it was swapped
----EXAMPLE1---- INPUT : 6 4 8 6 3 12 9 OUTPUT : 9 3 6 12 4 8
----EXAMPLE2---- INPUT : 4 42 28 84 126 OUTPUT : 126 42 84 28
Here's my code
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
int n ;
int input[51];
map<int,int> order ;
map<int,int> memo ;
bool valid(int a){
for(int i=0;i<n;i++){
if(input[i]==a)return 1 ;
}
return 0 ;
}
void dfs(int st){
memo[st]=1;
if(valid(st/3)){
if(memo[st/3]==0){
dfs(st/3);
order[st]+=order[st/3];
}
else order[st]+=order[st/3];
}
if(valid(st*2)){
if(memo[st*2]==0){
dfs(st*2);
order[st]+=order[st*2];
}
else order[st]+=order[st*2];
}
}
int main(){
cin >> n ;
for(int i=0;i<n;i++){
cin >> input[i];
memo[input[i]]=0;
order[input[i]]=1;
}
for(int i=0;i<n;i++){
if(memo[input[i]]==0)dfs(input[i]);
}
for(int i=n;i>=1;i--){
for(int k=0;k<n;k++){
if(order[input[k]]==i){
printf("%d ",input[k]);
break;
}
}
}
}
Information the OP should have told us in the first place:
my code gave the correct answer only 7 of 10 test case .i've already
asked my teacher he only told me to be careful with the recursion .
but i couldn't figure it out what's wrong with my recursion or
something else
An example that "fails":
Here's a failing case: Say you have the sequence 3 1 2 4. valid will
return true for 4 / 3 because it sees 1 in the sequence. –
Calculuswhiz
the better solution
#include<bits/stdc++.h>
using namespace std;
struct number{
long long int r , f3 , f2 ;
};
vector<number> ans ;
bool cmp(number a,number b){
if(a.f3!=b.f3)return a.f3>=b.f3;
if(a.f2!=b.f2)return a.f2<=b.f2;
return true ;
}
int main(){
int n ;cin>> n ;
long long int input ;
for(int i=0;i<n;i++){
cin >> input ;
long long int r = input ;
long long int f3 = 0, f2 = 0 ;
while(input%3==0){
f3++;
input/=3;
}
while(input%2==0){
f2++;
input/=2;
}
ans.push_back({r,f3,f2});
}
sort(ans.begin(),ans.end(),cmp);
for(auto i : ans){
cout << i.r << " " ;
}
}
The darkest place is under the lamp.
Look at the problem definition:
1.divide it by 3 (it has to be divisible)
Where do you test for the divisibility?
So, one error is here:
if(valid(st/3)){
This test should read:
if(st % 3 == 0 && valid(st/3)){
With this simple improvement, all three test cases pass.
A hint to improve (simplify) the solution
Numbers that are not divisible by 3 must come after those divisible.
Similarly, those not divisible by 9 must be coming after those that does.
Similarly for 27, 81,...
Now, if you divide your numbers into subsets of numbers of the form n = 3^k*m, where m % 3 != 0, then in each such a subset the only operation allowed by your algorithm is "multiply by 2". So it suffices to order them in ascending order.
The problem can be solved without dfs, nor is recurnece really necessary. Just order the numbers in a funny way: in descending order with respect to the number of times the number is divisible by 3, and then in ascending order. So, a task for you: challenge your teacher with a solution that, once the numbers are read in, does just one instruction std::sort (or qsort, as I see you write in C), then tests the validity of the solution, and prints it.
Moreover, I've just proved that if a solution exists, it is unique.

exited, segmentation fault

The input for this problem is a first number that indicates how many cases will be input to be analyzed.
Input:
3
8 12
9 27
259 111
The first number means that there will be 3 cases. The next 3 lines are the cases. The program has to output the GCD (Greatest Common Divisor) of the 3 cases.
4
9
37
The code I wrote looks like the following:
#include <iostream>
#include <vector>
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
int main() {
int N;
std::cin >> N;
int i = 0;
std::vector<int> cards;
while (i <= N) {
i++;
int F1, F2;
std::cin >> F1 >> F2;
cards[i] = gcd(F1, F2);
}
for (int j; j <= N; i++) {
i++;
std::cout << cards[i] << "\n";
}
}
It reads the first integer (number of test cases), runs the loop once (reads one test case) and stops running. The terminal outputs exited, segmentation fault. What is the problem?
In your code there are some problem, first of all you haven't setted the size of the vector, that result like it has 0 lenght.
Another error are the loops;
In fact in the firts one you add 1 to i before you do all the other operation, and in this way you'll start to insert from te second component of the vector (vector start his indexing at 0).
Also in the second loop there are some problems, for example you declare a variable j that it is totally usless becouse in the folowing operations you still use i (that is setted at the end value of the previous loop, the while one).
Try to correct this things and understand it and in this way you'll understand also the reason of your error, that is pretty common in c++.
I hope that i've helped you a bit :)

Why am I getting two outputs in place of a single one?

I'm writing a simple program and I am getting 2 outputs of the same data with a single cout statement. I think something went wrong with my loop, but I am not able to find where the problem is. If possible, please show me what I need to change; otherwise, I'd at least like to know why my logic is wrong.
My code:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int n ;
cin >> n;
vector<int> arr(n);
vector<int> a(n);
for(int arr_i = 0;arr_i < n;arr_i++){
cin >> arr[arr_i];
a[arr_i]=1;
}
int i,least,flag,count=n;
do{
cout<<count<<endl;
count=0;
flag=1;
for(i=0;i<n;i++){ //for getting least number
if(a[i]){
if(flag){
least=arr[i];
flag=0;
}
if(arr[i]<least){
least=arr[i];
}
}
}
for(i=0;i<n;i++){ // for actual logic
if(arr[i]<=0||!a[i]){
a[i]=0;
//continue;
}
else{
arr[i]-=least;
count++;
}
}
}while(count);
return 0;
}
Sample input:
6
5 4 4 2 2 8
Expected output
6
4
2
1
Actual output:
6
6
4
4
2
2
1
1
Problem statement
You are given N sticks, where the length of each stick is a positive integer. A cut operation is performed on the sticks such that all of them are reduced by the length of the smallest stick.
Suppose we have six sticks of the following lengths:
5 4 4 2 2 8
Then, in one cut operation we make a cut of length 2 from each of the six sticks. For the next cut operation four sticks are left (of non-zero length), whose lengths are the following:
3 2 2 6
The above step is repeated until no sticks are left.
Given the length of N sticks, print the number of sticks that are left before each subsequent cut operations.
Note: For each cut operation, you have to recalculate the length of the smallest sticks (excluding zero-length sticks).
One noticed error: when substracting least from arr[i] and arr[i] becoming <=0 a[i] still stays non-zero, and at next iteration you getting least number the same as at previous iteration.
Other problem: your count is count of previous turn. At first iteration it equals 6, because condition if(arr[i]<=0||!a[i]) dont fulfill for any number from input.
After fixing this part:
// for actual logic
if (a[i]) {
arr[i] -= least;
if (arr[i] <= 0)
a[i] = 0;
else
count++;
}
it looks working nice.

Understanding a loop output

Can somebody explain to me why the output will be as follows?
Why the loop runs a second time after (int i) gets as value 9, which is not less than 5?
It seems that even if (int i) is greater than 5 it still adds another 3 but the body won't run a second time. Why?
#include <iostream>
using namespace std;
int i=0;
int main()
{
for(;i<5;i+=3){
i=i*i;
}
cout << i << endl;
//Output: 12(i)
it works that way, more or less:
i = 0
i < 5 ? yes, keep on
i*i = 0
i+=3 => i ==3 now
i < 5 ? yes, keep on
i*i = 9
i+=3 => i is 12 now
i < 5 ? no, exit loop
You write a for(initialization; condition; excuteAtTheEndOfCycle):
initialization is executed only once at the beginning, condition is evaluated before each cycle, excuteAtTheEndOfCycle (i+=3, in your case), it's executed at the end of each cycle, before a further evaluation of condition
it is not running because you are giving condition of the loop to be less than five,
What are you want ,that output will be?

Prime number nested loop Logic

I am currently working on assignment which is stated below. My question is that why does my code only repeat prime number as 2 and not the remainder of the numbers. I would much appreciate if someone could help me to walk through the logic so i can try to solve the solution, rather than posting the answer outright. Kudos to all :)
Write a program that uses two nested for loops and the modulus
operator (%) to detect and print the prime numbers from 1 to 10,000.
(Prime numbers are natural numbers that are not evenly divisible by
any other number except for themselves and one). Display all the
primes found.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> n; // will store our values from 1-10000
for (int i= 0; i < 10000; i++) { // vector loading
n.push_back(i);
n[i]= n[i] + 1;
for (int j= 1; j < 10000 ; j++ ) { // Error is here?
if (n[j] % j == 0) { // supposed to go through all the numbers
// and flag the prime numbers
cout<<n[i] <<" is a prime";
i++;
break;
}
}
}
return 0;
}
The trivial method is rather easy to understand.
Outer loop (suppose the loop variable here is num) go through from 2 to 10000, and check every number whether it is a prime number.
Inner loop (suppose the loop variable here is fact) go through form 2 to num - 1
Check if num has a factor fact by num % fact == 0. If fact is a factor of num, then break the inner loop and continue to check the next number.
If after checking all the numbers from 2 to num - 1 and none of them is the factor of num, then we are sure that num is a prime number and continue to check the next number.
Note that 0 and 1 are special case so we exclude them from the loop.
This method doesn't need any array. The time complexity is O(n2) and space complexity is O(1).
BTW, there are other better solution to this problem, for example Sieve of Eratosthenes.
There are a couple of problems but for a starter consider the very first loop.
i = 0
n.push_back(i); // Now n[0] is now valid (having the value 0)
n[0] = n[0] + 1; // Now n[0] is still valid (having the value 1)
j = 1;
if (n[j] % j == 0) // Ups... access to n[1] which is invalid
// as you have only pushed one element, i.e. n[0]
Understand the purpose of your loops
The outer loop is the one that supplies the numbers, therefore you
don't need the vector
The inner loop is the one that does the checking
Where do you print?
The inner loop checks if a number is not prime. The only way it
knows this is if the number supplied by the outer loop is not divisible by any number supplied by the inner loop. Therefore the inner loop
does not print anything because it has to exhaust all checks before it knows that a number is prime
Your print statement should come last. This means it should be after the inner loop but still inside the outer loop and it should print the number if it is prime based on what was discovered by the inner loop. So you should have a way of knowing if the inner loop found a prime or not
Finally note that the inner loop has to start at 2 and end at i - 1 because every number is divisible by 1 and itself
Do not need to iterate through the entire range for inner loop, for inner loop there will possible values are starting from 2 to <= that number /2 .
Like if you want to check whether 99 is prime or not then you need to
set inner loop from 2 to 49 (99 / 2 is the max possible factor for
that number) so do not iterate through the rest all.
So if you iterate inner loop from 2 to 98 then it's meaning less to
iterate this loop after 49, think about it.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//vector<int> n; // will store our values from 1-10000
int flag =0;
for (int i= 2; i < 10000; i++) // vector loading
{
//n.push_back(i);
//n[i]= n[i] + 1;
flag =0;
for (int j= 2; j <= i / 2 ; j++ )
{
if (i % j == 0)
{
flag = 1;
break;
}
}
if(flag == 0)
{
cout << "%d number is Prime" << i;
}
}
return 0;
}