I couldn't get the point that " i "represents index inside the for loop - c++14

When we code somthing in the for Loop like
#include <iostream>
int main (){
int n;
cin >> n;
int arr[n];
For (int i =0 ; i<n ; i+2 ) {
cin >> arr[i];
if (arr[i] % 2 ==0) cout << "even";
else cout << " odd" ;
}
return 0;
}
In this code will the index of i will be updated by adding 3 or the value of index i ?

It's a very common problem for beginners.
According to your "for loop" (int i =0 ; i<n ; i+2 ) you're starting index is 0 and when you do i+2 it means increasing the value of the array index (i) by 2 and after updating the i value you reach array index 2 and then 4,6,8...
See some example
i++ or i=i+1 -> both means increasing the value of i by 1;
i+2 -> means increasing the value of i by 2;
i+3 -> means increasing the value of i by 3;
I think after reading this your doubt will be clear

Related

Finding number of occurrences of elements in array and printing them in in ascending order of elements

So, like the question says I want to arrange the occurrences of these elements in an ascending order of those elements. For example- if I input 7-3 times and 3-2 times, then output should be printed with 3-2 first and then (next line) 7-3. If you see the for loop with the comment to sort through the array, without that for loop the code works fine but doesn't print the elements in an ascending order. Let me know what you think about this and why that for loop isn't working?
#include<stdio.h>
int x;
int main()
{ int a[10000],b[10000],i,j,n,x,c=0,p,q ;
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
for(i=0; i<n; i++)
{ c=1;
if(a[i]!=-1)
{ for(j=i+1; j<n; j++)
{
if(a[i]==a[j])
{ c++;
a[j]=-1;
}
}
b[i]=c;
}
}
for (i = 0; i < n; ++i) \\for loop to sort a[i] elements in ascending order
{ for (j = i + 1; j < n; ++j)
{
if (a[i] > a[j])
{
x = a[i];
a[i] = a[j];
a[j] = x;
}
}
}
for(i=0; i<n; i++)
{
if(a[i]!=-1 && b[i]>1)
{
printf("%d-%d\n",a[i],b[i]);
}
}
return 0;
}
You can do it either in O(n * lg n) e.g. using sorting or in expected linear time using std::map, I'm not sure if there is something like this in C.
Example impl. w/ sorting:
#include <iostream>
#include <vector>
#include <algorithm>
std::vector<int> v = {3,7,7,7,3,7,7};
std::sort(v.begin(), v.end());
for (int i = 0; i < v.size(); ++i) {
int number = v[i];
int count = 1;
while (v[i + count] == number) ++count;
i = i + count;
std::cout << number << " " << count << std::endl;
}
If you know that range of elements in the array is small enough you can use radix sort and so get it done in linear time.
About your implementation.
You are good with the first loop.
In the second loop, you need to take into account -1 entries. Also you need to swap not only a but b entries as well.
Check for b[i] equals to 1. You can initialize it to 0 before c=1; and drop b[i] > 1 check.
Few more comments not related to correctness. Do not use magic number -1, give it a name, and then use it. Do not declare all variables at the beginning of the function, declare every variable as close as possible to the first use.

Google Kick Start 2020 Round A Allocation Problem - WA error

Problem
There are N houses for sale. The i-th house costs Ai dollars to buy. You have a budget of B dollars to spend.
What is the maximum number of houses you can buy?
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a single line containing the two integers N and B. The second line contains N integers. The i-th integer is Ai, the cost of the i-th house.
Output
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum number of houses you can buy.
int main(){
int tests, size, b;
cin >> tests;
for(size_t j = 0; j < tests; ++j){
cin >> size >> b;
int cur;
vector<int> prices(size);
for(size_t i = 0; i < prices.size(); ++i){
cin >> cur;
prices[i] = cur;
}
int cur_total = 0;
int count = 0;
sort(prices.begin(), prices.end());
int i = 0;
while(cur_total + prices[i] <= b){
++count;
cur_total += prices[i];
++i;
}
cout << "Case #" << j+1 << ": " << count << endl;
}
}
The above is my solution and when I run it locally with a test case, it is returning a correct output. Can anyone see a problem with my code??

Count the no of shifts in insertion sort using Fenwick tree (Binary index tree) in C++

I was attempting to solve the hackerrank problem on insertion sort that asks to calculate the number of shifts while sorting the array using insertion sort - https://www.hackerrank.com/challenges/insertion-sort/leaderboard. Seeing on the disccussion forums I get to know that using concept of binary index tree , the solution can be optimized for this question. I even understood the concept of BIT using link - https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/. But still I was not able to understand how it applies in this question. I may be sounding dumb , but any intutive explanation along with the below code that I found on the forum that uses BIT concept, but some more lucid explanation will help me a lot to actually grasp the solution.
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std ;
#define MAXN 100002
#define MAX 1000002
int n,a[MAXN],c[MAX] ;
int main()
{
int runs ;
scanf("%d",&runs) ;
while(runs--)
{
scanf("%d",&n) ;
for(int i = 0;i < n;i++) scanf("%d",&a[i]) ;
long long ret = 1LL * n * (n - 1) / 2 ;
memset(c,0,sizeof c) ;
for(int i = 0;i < n;i++)
{
for(int j = a[i];j > 0;j -= j & -j) ret -= c[j] ;
for(int j = a[i];j < MAX;j += j & -j) c[j]++ ;
}
cout << ret << endl ;
}
return 0 ;
}
it is in python. might it help you
def insertionSort(arr):
count = 0
bit = [0] * 10000001
bit_sum = 0
count = 0
for n in arr:
count += bit_sum
idx = n
while idx:
count -= bit[idx]
idx -= idx & -idx
idx = n
while idx < 10000001:
bit[idx] += 1
idx += idx & -idx
bit_sum += 1
print(count)
python code here

C++ - Queue pop not working corrrectly using using for() loop

While writing a simple code using STL queue and for loop, I faced a problem. My procedure is simple: take a number as a string, convert them into queue elements and show them.
My code is below :
#include<iostream>
#include<queue>
#include<string>
//#include<cctype>
using namespace std;
//int to_words(int i);
//int to_words_one(queue<int> &q);
int main()
{
queue<int> q;
string s;
cout << "Enter a number not more than 12 digits : ";
getline(cin, s, '\n');
for (int i = 0; i < s.length(); i++)
{
if (!isdigit(s[i]))
{
cout << "Not a valid number." << endl;
s.clear();
break;
}
}
if(s.size() > 0)
for (int i = 0; i < s.length(); i++)
q.push(s[i] - '0');
while (!q.empty())
{
cout << q.front();
q.pop();
}
system("PAUSE");
}
It works fine. No problem. But instead of while(!q.empty()), if I use
for(int j=0;j < q.size(); j++)
{
cout << q.front();
q.pop();
}
It doesn't work properly! It just shows and pops some first elements , and NOT ALL elements of the queue and prompts for Press any key to continue. Please tell me why is this happening? Shouldn't while(!q.empty()) and and that for() loop work similar?
The problem is that q.size() decreases after each q.pop() and is evaluated in each iteration of the for loop. For instance, let's say you had 6 elements in your queue, the for loop state in subsequent iterations will be as below:
i = 0, q.size() = 6,
i = 1, q.size() = 5,
i = 2, q.size() = 4,
i = 3, q.size() = 3,
so only first 3 elements would be printed. If you want to use a for loop, save q.size() to a variable before the first iteration, like this:
int q_size = q.size();
for (int i = 0; i < q_size; i++) {
// do something
}
By calling queue::pop size of queue is decremented, so suppose you entered 8 digits, in first iteration of for loop q.size() returns 8, then you compare j < 8 it is true and j is incremented and size of queue is decremented. In the next iteration of loop for you compare j < 7, where j is 1. Do 2-th, 3-th iterations... After 4-th iterations j counter has value 4, and size of queue is 4 too, so condition j < 4 returns false, and only 4 digits were printed.

How do we solve the given scenario efficiently?

We are given a maze in which we need to visit as many rooms as possible. The specialty of the maze is that once you enter any room it will only lead you to rooms with a higher tag in the direction you move . B and C decide to move in opposite directions trying their luck to maximize the number of rooms they search .(They can start with any room , need not be the same)
We need to find out the maximum number of rooms that can be searched.
1. Access to any room with a higher tag is allowed, not just adjacent rooms or the next room with a higher tag.
2. Tags are unique.
So given the input:
12 11 10 1 2 3 4 13 6 7 8 5 9
the answer is 12: (1,2,3,4,6,7,8,9) for B and (5,10,11,12) for C.
I thought of solving this using longest increasing sub sequence first from right and then from left.And the count of unique elements in above two sub sequence would be the answer.
But my logic seems to fail,how can this be done?
My program below computes the maximum number of rooms searched. This has time complexity of O(n^3). I modified the DP algorithm for computing the longest increasing sequence available online to solve OP's problem. This also addresses OP's concerns on arrays like {1,4,6,2,5}. I rightly get the max value as 5 for the previous example. So, I used the idea from #BeyelerStudios that we need to compute the longest increasing subsequence from both left to right and from right to left. But, there is a caveat. If we compute the Left to right max sequence, the sequence from right to left should be on the remaining elements. Example:
For the array {1, 4, 6, 2, 5}. If the forward rooms selected are {1, 4, 5 }, then the reverse longest increasing sequence should be computed on the left out elements {6, 2}.
Below is my program:
#include <iostream>
using namespace std;
// compute the max increasing sequence from right to left.
int r2lRooms (int arr[], int n)
{
int dp[n];
int i =0, j = 0;
int max = 0;
for ( i = 0; i < n; i++ ) {
dp[i] = 1;
}
for (i = n-2; i >= 0; i--) {
for ( j = n-1; j > i; j-- ) {
if ( arr[i] > arr[j] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
}
}
}
for ( i = 0; i < n; i++ ) {
if ( max < dp[i] ) {
max = dp[i];
}
}
return max;
}
// compute max rooms.
int maxRooms( int arr[], int n )
{
int dp[n], revArray[n];
int i =0, j = 0, k = 0;
int currentMax = 0;
int forwardMax = 0, reverseMax = 0;
for ( i = 0; i < n; i++ ) {
dp[i] = 1;
}
// First case is that except for first elem, all others are in revArray
for (i=1; i < n; i++, k++) {
revArray[k] = arr[i];
}
reverseMax = r2lRooms (revArray, k);
forwardMax = 1;
if (currentMax < (forwardMax + reverseMax)) {
currentMax = forwardMax + reverseMax;
}
cout << "forwardmax revmax and currentmax are: " << forwardMax << " " << reverseMax << " " << currentMax << endl;
cout << endl;
for ( i = 1; i < n; i++ ) {
k = 0;
forwardMax = 1;
reverseMax = 0;
cout << "Forward elems for arr[" << i << "]=" << arr[i] << endl;
for ( j = 0; j < i; j++ ) {
if ( arr[i] > arr[j] && dp[i] < dp[j] + 1) {
dp[i] = dp[j] + 1;
forwardMax = dp[i];
cout << arr[j] << " ";
}
else {
// element was not in DP calculation, so put in revArray.
revArray[k] = arr[j];
k++;
}
}
// copy the remaining elements in revArray.
for ( j = i+1; j < n; j++ ) {
revArray[k] = arr[j];
k++;
}
cout << endl;
reverseMax = r2lRooms (revArray, k);
if (currentMax < (forwardMax + reverseMax)) {
currentMax = forwardMax + reverseMax;
}
cout << "forwardmax revmax and currentmax are: " << forwardMax << " " << reverseMax << " " << currentMax << endl;
cout << endl;
}
cout << " Max rooms searched " << currentMax << endl;
return currentMax;
}
int main (void) {
int arr[] = {12, 11, 10, 1, 2, 3, 4, 13, 6, 7, 8, 5, 9 };
int size = sizeof(arr) / sizeof(int);
cout << maxRooms (arr, size);
}
I think the trick is at the intersection, where B and C might share a value or there's options to go around that (say the sequence is 12 11 10 1 2 3 4 <3 5> 13 6 7 8 9 The extra numbers here adds 1 to the solution, but doesn't change the result for either longest increasing sub-sequences.
So the only problem is the one room in the middle, since on both side the values chosen diverge.
What I would do is this: do the longest subsequence in one direction, figure out a solution (any solution), take out the numbers in the solution and do the longest subsequence in the other direction. This way if there's a way around the crossing room in the middle the second pass will prefer it, unless that's the chosen number is really needed. To check for that do the same thing, but build the first subsequence in the opposite direction and the second one (after removing the solution) in the direction chosen initially.
Complexity remains O(N) but with a slightly higher constant factor.

Resources