I was practicing with google kickstart's round B bus route problem. I actually looked at their analysis and implemented their alternative answer.
I'll also paste the problem prompt below my code.
https://codingcompetitions.withgoogle.com/kickstart/round/000000000019ffc8/00000000002d83bf
And my solution passes the first test set but gets a wrong answer on the second test set. I have no idea what the second test set is, only that it's very big. I'm pretty confused as my solution follows the analysis of the problem, and is actually an implementation of the alternate provided solution to a T. I also have no idea how to figure out which test case could be giving a wrong answer, there seems to be so many possibilities!
I have no idea how to even debug such a vague answer. Maybe there are some edge cases I'm not considering?
#include <iostream> // includes cin to read from stdin and cout to write to stdout
#include <bits/stdc++.h>
using namespace std;
int main() {
int t, n, d;
cin >> t; // read t. cin knows that t is an int, so it reads it as such.
for (int i = 1; i <= t; ++i) {
cin >> n >> d; // read n and then m.
stack <int> bus;
for(int j=0; j<n; j++){
int x;
cin >> x;
bus.push(x);
}
while(!bus.empty()){
int b = bus.top();
bus.pop();
d = d - d%b;
}
cout << "Case #" << i << ": " << d << endl;
}
return 0;
}
****Here's a shortened version of the Problem Prompt ****
Problem
Bucket is planning to make a very long journey across the countryside by bus. Her journey consists of N bus routes, numbered from 1 to N in the order she must take them. The buses themselves are very fast, but do not run often. The i-th bus route only runs every Xi days.
More specifically, she can only take the i-th bus on day Xi, 2Xi, 3Xi and so on. Since the buses are very fast, she can take multiple buses on the same day.
Bucket must finish her journey by day D, but she would like to start the journey as late as possible. What is the latest day she could take the first bus, and still finish her journey by day D?
It is guaranteed that it is possible for Bucket to finish her journey by day D.
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a line containing the two integers N and D. Then, another line follows containing N integers, the i-th one is Xi.
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 latest day she could take the first bus, and still finish her journey by day D.
Limits
Time limit: 10 seconds per test set.
Memory limit: 1GB.
my guess is using int is not sufficient as D can be up to 10^12 in test set 2
Edited: I verified my guess. You will be able to solve the problem by fixing this bug. And I believe the use of long long is common for coding contests, i.e. take note of the input/output constraints every time.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main ()
{
int t;
long long int x,i,j,n,d;
cin >> t;
for ( i = 0; i < t; i++)
{
cin >> n >> d;
stack < long long int >route;
for (j = 0; j < n; j++)
{
cin >> x;
route.push (x);
}
while (!route.empty ())
{
long long int c = route.top ();
route.pop ();
d = d - d % c;
}
cout << "Case #" << i+1 << ": " << d << endl;
}
return 0;
}
Related
I'm taking an elementary programming course where we use C++ and I'm stuck on a couple of assignments. Please excuse my potentially bad terminology going forward. Part of my basic program I'm writting asks "Write down 5 integers: " and then the user gets to pick the integers and a message "You wrote the integers: n1 n2 n3 n4 n5" is returned. There are several of these questions and I'm not allowed to use more then one variable of the same type. The problem is that the user could respond with n1 n2 n3 n4 n5 hello, and hello is supposed to be ignored. How do I accomplish this?
If we for a moment assume that we are only to write down one integer instead of 5, then perhaps something along the lines of the code below would work.
#include <iostream>
using namespace std;
int main()
{
int num;
cout << "Write down an integer: "
<< flush;
cin >> num;
cout << "You wrote the integer: "
<< num
<< endl;
}
But how do I do this with five integers. Further, how do I ignore that extra hello? I'm assming that cin.ignore is to be used here somehow.
If you want to repeat the procedure 5 times, you could just copy-paste it, but that's definitely not a good practice. What's much better is to use a loop/cycle, like for.
You'll also need to store all 5 integers into memory. You could use 5 variables (int n1, n2, n3...), but again, that's not a very good practice and as you state, that's not allowed in your case. Solution is to use an array, which can hold several values of the same type.
Here is a working example with explaining comments:
int nums[5]; // this array will hold 5 integers
int n;
cout << "Write down 5 integers:" << endl;
for (n = 0; n < 5; ++n) { // run code in the braces 5 times
cin >> nums[n]; // store typed integer into nth position of the array
}
cout << "You wrote: ";
for (n = 0; n < 5; ++n) { // run code in the braces 5 times
cout << nums[n] << " "; // print integer at nth position of the array
}
Note: One could say that both nums and n are of the same type, int. In that case, you could extend the array nums to the size of 6 items and use the last one (to which you can refer as nums[5]) as an indexing variable for the loops.
I was doing basic programming to print the n's table in reverse order where n is a positive integer.
Here is my approach:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n;
cin >> n;
int multiplier = 10;
while (multiplier--)
{
n = n*multiplier;
cout << n << endl;
}
}
But its output is not what I expected. May I know where is the problem lying in this code? Also, please do provide me some advice as after 2 months I am having MS intern interview.
My input was
2
Output came out to be
18
144
1008
6048
30240
120960
362880
725760
725760
0
I guess you probably don't want to change n every iteration, so I suggest you assign the calculation to another (scoped) variable:
int main()
{
int n;
cin >> n;
int multiplier = 10;
while (multiplier--)
{
int nn = n*multiplier;
cout << nn << endl;
}
}
Another thing: you might want to actually see the 10*n printed first (and not the "0" at the end), so you could also multiply n by multiplier+1 (or do a do-while loop instead).
I'm still very new to C++ still and decided to make a fibonacci sequence. It worked (Woo!) but it doesn't work as well as I would like it to.
what I mean by that is say for example I told my program to count the first 10 terms of the sequence I will get
"0, 1, 1" and then I have to press enter for each additional number until it hits ten in which case the program returns 0 and ends.
How do I get the program to display all the numbers I want to without hitting enter for each additional one?
Here is my script:
#include <iostream>
using namespace std;
int main()
{
int FibNum;
cout << "How many numbers of the Fibonacci Sequence would you like to see? \n\n";
cin>> FibNum;
cin.ignore();
int a = 0;
int b = 1;
int c = 2;
cout << "Fibonacci Sequence up to " << FibNum << " terms.\n\n";
cout << a << "\n" << b << "\n";
for (int c = 2; c < FibNum; c++) {
int d = a + b;
cout << d;
cin.ignore();
a = b;
b = d;
}
}
Thanks in advance for any help!
P.s. Also if you notice anything terrible I'm doing please feel free to correct me, I'm very aware I'm probably doing a lot wrong, I'm just trying to learn. :]
A few things:
1) Remove int c = 2; as you're re-defining c inside the for loop.
2) Drop the line cin.ignore();: in your for loop: that will fix your "enter" problem; that line waits for some input then ignores it.
3) Put some white space in your output: e.g. cout << d << ' ' so your numbers are separated.
4) [Acknowledge vincent_zhang] Consider moving to uint64_t as your data type for a, b, and d. This is a standard type in C++11. It's a 64 bit unsigned integer type; adequate for a large number of terms.
and a small thing, bordering on personal opinion,
5) Use ++c instead of c++ as the former will never run slower as, conceptually at least, post-increment has to take a copy of the original value.
Besides the previous answers,
To better format the output, add white space by changing this
cout << d;
to
cout << d << " ";
You may want to change the type of a, b and d from int to double to prevent overflow.
(If you let FibNum=100 in your code, you should be able to observe overflow, meaning that you are going to get some incorrect numbers toward the end of the sequence.)
Move cin.ignore() out of the loop then you dont need to enter to print all the 10 numbers of Fibonacci series
I'm not sure how to title my question, but here goes. I am testing some features, and I have hit a snag.
What I want to know is how can I set up a "for" or "if" statement to only put values in an array that meet a criteria? For example, find every divisor for a number, but only put factors in an array.
Any help would be loved, source code can be provided if needed :). Yes, I am new, so be gentle!
#include <iostream>
using namespace std;
int main(){
int n;
int counter = 1;
cout << "What number would you like to use? ";
cin >> n;
int DiviArray[n];
for (int k=0,j=1;k<n;k++,j++)
{
DiviArray[k] = n-k;
}
int k = 3;
int factn[n];
cout << "Factors of " << n << ": " << endl;
for (int i=0, j=1;i<n;i++,j++)
{
factn[i] = n/DiviArray[i];
if(factn[i]*DiviArray[i]==n)
{
cout << counter << ". " << factn[i] << " x " << DiviArray[i] << endl;
counter++;
}
}
return 0;
}
EDIT: Decided to go with vectors, not sure if I can get it to work, but thanks for the feedback guys :)
Since you don't know in advance how many values will meet the condition, you should use a std::vector.
As a benefit, it keeps track of how many elements you've already added, so push_back will always use the next available index.
This also fixes
cin >> n;
int DiviArray[n];
which isn't legal C++.
If you only want to put the values into the array that match the condition, then you should only put a number into the array when the condition is matched. To do that, the statement that puts a number into the array has to be inside the if-block for the condition. I hope I don't need to explain why :)
This is the only time in your program where you actually do want two indices: one that is incremented every time through the loop (to count how many times to run the process), and one that is incremented only when you put a number in the array (to figure out where the next number goes). Everywhere else, you've created a completely useless j variable (the uselessness should be apparent from the fact that there is no code that actually uses the value, only code to set it).
I am brand new to this site. A friend told me about it and how much it has helped him, so here goes!
I am trying to create a program that will read in a certain size of a group. At this point it will then create random birthdays for each 'member' of the group (a day 1-365) and then compare to see if there were any identical birthdays in that set. The program will do this comparison for a given group size 10,000 times and keep track of how many of those trials yielded an identical birthday and return a percentage of the 10,000 trials in which there was a match.
The problem I am having is that the program will only ever return 100% and each successive run doubles that. So if a user decided to run again with a different group size, the answer then becomes '200%' then '300%' and so on.
Any help with this will be greatly appreciated!
//This program will ask for the number of people in a group and then output
//percentage likelyhood that two birthdays occur on the same day.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int bdays [365];
const int loop = 10000;
int identicalBday;
void setZero (int []);
int totalDoubles (int [], int);
int main()
{
int grpSize = 1;
cout << "This program will ask for the number of people in a group and then output \npercentage likelyhood that two birthdays occur on the same day.";
cout << "\nHow many in group (0 quits)? ";
cin >> grpSize;
while (grpSize != 0)
{
int identicalBday = 0;
setZero (bdays);
cout << "In a group of " << grpSize << " the chances that two birthdays are the same is " << totalDoubles (bdays, grpSize) << "%." << endl;
cout << "\nHow many in group (0 quits)? ";
cin >> grpSize;
}
cout << "Thanks for using this program.";
cin.get();
cin.get();
return 0;
}
//Sets all indicies to 0
void setZero (int bdays [])
{
for (int i = 0; i < 365; i++)
bdays [i] = 0;
}
//Will add one to the array index associated with the random rumber
//If that index is already equal to 1, then it breaks (at least one other identical birthday exists)
//When it does break, will add one to the indenticalBday, allowing for division at the end
int totalDoubles (int bdays [], int grpSize)
{
int tmpRand;
for (int k = 0; k <= loop; k++)
{
for (int i = 0; i <= grpSize; i++)
{
srand((unsigned)time(0));
tmpRand = rand() % 365;
if (bdays[tmpRand] == 1)
{
identicalBday++;
break;
}
else
bdays [tmpRand]++;
}
}
return (identicalBday/loop)*100;
}
There are various errors with this code.
As Gabe mentioned it, the int identicalBday = 0 is local and doesn't reset the global one, which explain your 100% increase between runs. I think this error could be avoided by using a simple coding style rule: declare the variable where/when they are needed, that is the most locally possible and not at global level. For example, identicalBday and bdays should be declared inside totalDoubles(). Doing so will also remove all the side-effects of this function, and guarantee that everything is reset between calls.
By recalling srand() at each step, you reset the seed to the same value (time doesn't change fast enough) and kill all randomness. Only call it once.
You forget to recall setZero(bdays) after each grpSize loop.
(identicalBday/loop)*100; incorrectly do an integer division and round the result to 0 (or 1 if the srand error is not fixed). Use float division.
Fixing those seems to give correct result here (e.g. the classic 23 gives 53%)
Your problem is the line int identicalBday = 0; -- can you guess why?
Since you have int at the beginning, you are declaring a new variable that only exists within your while loop. That leaves the global identicalBday uninitialized, meaning that it never gets reset so it increases every time through the loop.