I realize that there are many questions with this title on SO, but all of the ones I've found did things like i = ++i or f(f(f(x))), neither of which are in this code. It's an attempt at a backtracking solution to this. I have some experience with C but I've just started trying to pick up C++, and I've been doing Codeforces problems for practice. The snippet below is the main body of the program. main, which I have not shown, deals with input and output. I used global variables here for weights, answer, and max_depth in the interest of keeping each stack frame of solve as small as possible.
The input that's causing trouble is weights = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} and max_depth = 1000. When I compile this with g++ std=C++11 file.cpp, it gives "4 3 2 3 4 3 2 3 4 ... 3 2 1," which is the correct answer. When Codeforces compiles it, it gives "9 10 9 10 9 10 9 10...", which is incorrect. My guess is that the order that for(int i : weights) traverses the vector in is not defined by the standard, but even then, I don't see why it would make any difference. What am I missing?
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
string answer = "";
vector<int> weights;
int max_depth;
bool solve(int left_scale, int right_scale, int last_added, int depth){
bool is_left = (depth % 2) == 0;
int new_weight;
int weight_to_inc = is_left ? left_scale : right_scale;
int weight_to_exceed = is_left ? right_scale : left_scale;
if (depth == max_depth){
return true;
}
for(int i : weights){
if (i != last_added){
new_weight = weight_to_inc + i;
if (new_weight > weight_to_exceed){
bool ans = solve(is_left ? new_weight : left_scale,
is_left ? right_scale : new_weight,
i, depth + 1);
if (ans){
stringstream ss;
ss << i;
answer.append(ss.str() + " ");
return true;
}
}
}
}
return false;
}
void start_solve(void){
if (solve(0, 0, 0, 0)){
return;
}
answer = "";
}
(The full code that I submitted, if it makes any difference, is here.)
EDIT:
In case anyone stumbles on this looking for an answer to the Codeforces problem: the issue with this code is that "answer" is reversed. Changing answer.append(ss.str() + " ") to answer = ss.str() + answer is the shortest fix that gets it working.
Why does this C++ code give different output on different compilers?
It doesn't give different output.
When I compile this with g++ std=C++11 file.cpp, it gives "4 3 2 3 4 3 2 3 4 ... 3 2 1," which is the correct answer. When Codeforces compiles it, it gives "9 10 9 10 9 10 9 10...", which is incorrect.
I believe you are misinterpreting your test results on the codeforces server.
The correct answer is "9 10 9 10...".
The output of your program is "4 3 2 3 4 3..." on both the codeforces server and your local workstation.
So your algorithm is wrong, and the output of the program is consistent.
You are mixing up the two fields on the test results "Output" and "Answer".
Check your test results again.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am taking a course on edx.org Introduction to C++ by Microsoft. I get unwanted output when looping through a single dimensional array. The code is below.
<#include <iostream>
int main() {
int arrayName[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 1; arrayName[i] <= 20; i++) {
std::cout << i << std::endl;
}
The output of this is:
1
2
3
4
5
6
7
8
9
10
11
Where does the 11 come from? And, if I make i=0, it also prints a 0. How does it print more than 10? And, when I try to change arrayName[10] to arrayName[9], I get a compiler error that there are too many initialized values:
int arrayName[10] = { 1,2,3,4,5,6,7,8,9,10 };
do {
std::cout << i << std::endl;
i++;
} while (arrayName[i] < 5);
The output is:
12
13
14
15
16
17
18
That do-while loop outputs 7 integers that I did not specify to be included in the arrayName[] array.
I don't know what I am doing wrong or what I am not understanding.
Please help. Thank you!
First, note that arrays in c++ start at index 0. So in int arrayName[3] = {10, 42, 88}; then arrayName[1] is 42, not 10. That means the last element in this array is int arrayName[2]. There is no element at index 3.
Your array only contains 10 elements (indices 0 to 9). The standard does not specify what happens when you access an element past the end of an array, anything can happen. In your case, arrayName[10] and arrayName[11] happens to give you something less than or equal to 20, and then arrayName[12] gave you something greater than 20, ending the loop. If you try it on another computer, or even at a different time, the results will vary. It might also crash (this is the best case scenario).
See this answer for more information on undefined behavior.
I finally found this: Correct way of loop through the C++ arrays, answer by https://stackoverflow.com/users/1619294/mark-garcia.
Changed my code to:
std::cout << "Looping through arrayName3 with std::array and letting the compiler determine how many objects to print:" << std::endl;
// Need to #include <array>
std::array<int, 10> arrayName3 = { 1,2,3,4,5,6,7,8,9,10 };
for (const auto& i : arrayName3) // Range-for
{
std::cout << i << std::endl;
}
The output was what I wanted:
1
2
3
4
5
6
7
8
9
10
This let's the compiler know it is deciding what to output. It would be great to know how to change this to control how many indices to loop through.
Please explain me how the code i am providing gives the output as :
1 2 3 4 5 6 7 8 9 10 11
#include<stdlib.h>
#include<iostream.h>
int main()
{
randomize();
int Num, Rndnum;
cin >> Num;
Rndnum = random(Num) + 7;
for (int N =1; N<=Rndnum; N++)
cout << N <<"";
}
Please explain me this code snippet
Well you are taking an input Num from the user and passing that to a random() function. You are then taking the returned value from that function and adding 7 to it and assigning it to Rndnum. Finally you are looping through from 1 to the Rndnum and printing of each of those numbers (1, 2, ...., Rndnum).
In the case of printing out 1 - 11 you must have gotten a return value of 4 from random(Num).
since I cannot see neither the function randomize() nor random(), I cannot tell you what they do but in this case the function call random(Num) gives back a 4, so Rndum adds up to 11.
Lastly, the for-loop repeates 11 (1 to inclusively 11) times and each time the output is the counter N itself.
So depending on what random does to your variable Num the number of iterations of your loop change.
Hope that helps!
P.S. If you want to look into random numbers in c++, take a look here
C++ rand
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
srand(time(NULL));
int main(){
int botguess;
int playerinput;
int mi=1, ma=100;
int turns = 0;
cout<<" what do you want guessed:";
cin>> playerinput;
cout<< "time for me to start guessing\n";
for(int i = 0;i < 50;i++) {
botguess = rand() % ma + mi;
if(playerinput > botguess){ //<--the problem
mi = botguess;
}
if(playerinput < botguess) {
ma = botguess;
}
cout<<"Max:"<<ma<<"\n"<<botguess<<"\n";
Sleep(1000);
if(botguess == playerinput)
{
cout<<"you win";
}
}
cin.get();
return 0;
}
So I've been tearing my hair out about why logically this doesn't work. This is a program that is supposed to guess the players number quickly but not instantly. The program doesn't perform like it looks.
The line that I noted causes a bug where the max number possible is being ignored. im getting number that are 100+ but under 200 and i don't know why. When I remove the lines concerning the mi variable nested in the statement in the for loop. The program doesn't go over 100 but I don't get the other end of the program solving the player number.
Also if you figure it out can you please explain it to me I don't just want a answer.
botguess = rand() % (ma - mi + 1) + mi
You don't want ma different numbers, you want much less of them. Look at an example: (5..10) contains 6 different numbers: [5, 6, 7, 8, 9, 10]; but if you do rand() % 10 + 5, you're getting numbers from 5 (5 + 0) to 14 (5 + 9). What you need is rand() % 6 + 5, where 6 is 10 - 5 + 1.
The problem you are having is caused by the fact that mi is set to botguess, which can easily be greater than zero, then on the next cycle if ma is still 100 (or anywhere near it), you're going to sometimes get numbers greater than 100 set into botguess.
Edit added: the % operator in C++ is mod division (ie. gives the remainder of integer division) So for example, 98 % 100 + 15 will be 98 + 15, i.e. 113
This link may help you:
http://www.cplusplus.com/reference/cstdlib/rand/
Codeforces problem 158B-http://codeforces.com/problemset/problem/158/B
I am getting an unexpected output for test case 5.I think I should get 1 as output but I am it as 2.Please guide me.Judge's log:
Test: #5, time: 30 ms., memory: 380 KB, exit code: 0, checker exit code: 1, verdict: WRONG_ANSWER
Input
2
2 1
Output
2
Answer
1
Checker Log
wrong answer expected 1, found 2
My solution:
#include<iostream>
using namespace std;
int n,a[100000],i,b,c,d,e,f,g,h;
int main()
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
b=0;
c=0;
d=0;
e=0;
for(i=0;i<n;i++)
{
if(a[i]==1) //To check for number of 1,2,3 and 4 membered groups.
b=b+1;
if(a[i]==2)
c=c+1;
if(a[i]==3)
d=d+1;
if(a[i]==4)
e=e+1;
}
f=e;
if(d>b) //More 3 member groups than 1.
{
f=f+d; //f=f+b+(g-b) 3 and 1 member groups combine.Remaining 3 i.e. (g-b) member groups will can't combine with 2 member groups.Hence,they take separate taxies.
g=-1;
}
if(b>=d) //More 1 member groups than 3.
{
f=f+d;
g=b-d; //g=remaining 1 member groups.
}
h=(2*c)%4; //Empty seats in last taxi.Possible values can be 0,1,2,3.
if(h==0)
f=f+(c/2);
else
f=f+((c+1)/2);
if(g!=-1)
{
g=g-h; //Remaining 1 member groups after combining with remaining seats in last 2 member taxi.
if((g%4)==0)
f=f+(g/4);
else
f=f+(g/4)+1;
}
cout<<f;
}
If your input is 2 2 1, then b and c will both be 1, making f 0 and g 1 in the first set of conditionals. h will be (2 * 1) % 4 or 2, making an update to f (0 + 1 = 1). Since g is 1, g-h is -1, which will lead to you executing f=f+(g/4)+1 which is f=1 + (-1/4)+1 which is 1 + 0 + 1 = 2 in integer math.
I think you wanted to check if g-h>0 instead of g!=-1, but there are a ton of places you could simplify your code. Note that using a debugger and stepping through this would have shown you where your problems are much faster, and be much more helpful to increasing your skills, than asking SO.
Just for anyone else looking at this question, this is a fairly simple answer to the problem.
Do it by hand and see if you get the same answer. If you get the same answer by hand as the computation, your algorithm is wrong. If you don't, your code is wrong.
Print variables from intermediate computations to see if they are what you think they should be.
Make sure, if it might matter, that you reinitialize your variables (including arrays) before each use.
Other tips:
Use a switch statement instead of multiple if-equal statements.
Name your variables. It helps you keep track when looking at your code.
When you have multiple variables with similar use, consider using an array instead. b, c, d, and e all seem similar.
I want a table of four values between 1 to 6.
I'm using: rand() % 6 + 1;
This should give values between 1 and 6.
Except if rand() generates the value 0.
I keep getting 7's. I don't want any 7's
What is the range of rand? How I prevent it from generation any 0 values?
Alternative solutions are quite welcome.
My teacher gave us the clue of using "random".
We use Borland C++ Builder 5 at school.
I am using Dev-C++ 5.3.0.3 at home.
I find there are a few differences to how they work, which I find strange..
I can't use random(), it gives me not declared in scope...
int main (){
int I;
int Fasit[3];
srand (time(NULL) );
for(I=0; I<4; I++) {
Fasit[I]=rand() % 6 + 1;
}
std::cout << Fasit[0] << " " << Fasit[1] << " " << Fasit[2] << " " << Fasit[3] << " ";
return 0;
}
Some values I get:
2 6 1 7
5 2 1 4
5 2 1 4
5 2 1 4
1 3 1 6
5 3 3 7
5 3 3 7
5 3 3 7
7 shouldn't be possible, should it?
PS: I know my print is ham fisted, I will make it a bit more elegant once the number generation works.
Consdier these lines:
int Fasit[3];
for(I=0; I<4; I++) {
Fasit[I]
You declare an array of three entries, which you write to four times.
Try your program again, but with:
int Fasit[4];
You only have 3 elements in Fasit[3]; When you write to Fasit[3], you are in the realm of undefined behavior, which in this case manifests it self with apparent contradiction.
Fasit[3] allows you to access only Fasit[0], Fasit[1], and Fasit[2].
Accessing Fasit[3], either for reading and writing, is undefined behavior. Your code is both writing and reading to Fasit[3] :-). The program is accessing the array out-of-bound. Fix it!
As to why 7 is printed, that is just coincidence. Note that Fasit[0-3] is always printed in the range 1-6 as you expected.
See also:
Array Index out of bound in C
Bounds checking
int Fasit[3];
You are creating an array of size 3, which can be accessed with indexes 0, 1 or 2 only.
You are writing and reading Fasit[3], which has an undefined behaviour. When a behaviour is undefined, you are bound to obtain weird results. This is it.