I have a uni project the task is We flew from Europe to North America, and we measured the height above the sea level at equal sequences. The first and last measurements were either above a continent or the sea. We measured positive height, where we were above some land, and 0, where we were above the sea
I tried to make the code and now i have the code and when i enter the inputs it gives me the same output as it is supposed to be in the task.
The problem is that the code doesn't work in the university online marking system, because
I checked it in case there are no islands, the program prints 0 0, but it should print a single 0.
Also, when all the islands have 0 valleys, the program should just show output of the first island, right now the maximum selection doesn't work for this case (do you think it can fixed by changing only the initial value of maxV)
Can you please help me with these two points?
#include <iostream>
int main() {
// Gets the number of heights
unsigned int height_count;
std::cin >> height_count;
// Get every height recorded and put it in an array
unsigned short* heights = new unsigned short[height_count];
for (int i = 0; i < height_count; ++i)
std::cin >> heights[i];
// We need to keep track of the following things:
int island_start = -1, max_island_start = -1, max_island_end = -1;
unsigned current_valley_count = 0, max_valley_count = 0;
for (int i = 1; i < height_count-1; ++i) {
if (heights[i] > 0 && heights[i-1] == 0) // If the coast starts
island_start = i;
else if (heights[i] > 0 && heights[i] <= heights[i-1] && heights[i] <= heights[i+1] && !(heights[i] == heights[i-1]) + (heights[i] == heights[i+1]) == 1) // If there is a valley
++current_valley_count;
else if (heights[i] > 0 && heights[i+1] == 0) { // If the coast ends
// Checks if the last island checked had the most valleys
if (current_valley_count > max_valley_count) {
max_island_start = island_start;
max_island_end = i;
max_valley_count = current_valley_count;
}
island_start = -1;
current_valley_count = 0;
}
}
std::cout << max_island_start+1 << " " << max_island_end+1 << std::endl;
return 0;
}
To print single 0 instead of 0 0, you should add if statement to check if there were no islands and change what to print according to that.
Also, the initial value of max_valley_count should be -1 instead of 0 so that the (first) island with 0 valleys can appear in the output.
I don't think the issue can be fixed by changing initial value of maxV because maxV is not used in this code.
As one more point, the problem statement says
but only one of B=A and B=C is true
On the other hand, your program says
!(heights[i] == heights[i-1]) + (heights[i] == heights[i+1]) == 1
This part of code means "only one of B!=A and B=C is true".
You should delete the !.
Related
This problem has been asked here but that's not what I am looking for.
Greetings everybody! I was solving the broken necklace problem which is a USACO Problem. Here is the problem:
You have a necklace of N red, white, or blue beads (3<=N<=350) some of which are red, others blue, and others white, arranged at random. Here are two examples for n=29:
1 2 1 2
r b b r b r r b
r b b b
r r b r
r r w r
b r w w
b b r r
b b b b
b b r b
r r b r
b r r r
b r r r
r r r b
r b r r r w
Figure A Figure B
r red bead
b blue bead
w white bead
The beads considered first and second in the text that follows have been marked in the picture.
The configuration in Figure A may be represented as a string of b's and r's, where b represents a blue bead and r represents a red one, as follows: brbrrrbbbrrrrrbrrbbrbbbbrrrrb .
Suppose you are to break the necklace at some point, lay it out straight, and then collect beads of the same color from one end until you reach a bead of a different color, and do the same for the other end (which might not be of the same color as the beads collected before this).
Determine the point where the necklace should be broken so that the most number of beads can be collected.
Example:
For example, for the necklace in Figure A, 8 beads can be collected, with the breaking point either between bead 9 and bead 10 or else between bead 24 and bead 25.
In some necklaces, white beads had been included as shown in Figure B above. When collecting beads, a white bead that is encountered may be treated as either red or blue and then painted with the desired color. The string that represents this configuration can include any of the three symbols r, b and w.
Write a program to determine the largest number of beads that can be collected from a supplied necklace.
Actually I tried to solve the problem using C++. However, I seem to be getting a wrong answer in case 3 which is
77
rwrwrwrwrwrwrwrwrwrwrwrwbwrwbwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwr
My code outputs 72 but the answer is 74. I can't even see how the answer is 74 (don't we have to subtract that 5 b block to get 77-5=72) How do we get 74? How is my code wrong and which cases am I missing? I can't seem to be able to debug this code...
Any helps would be appreciated. Thank You.
#include <bits/stdc++.h>
using namespace std;
int main(){
//For faster I/O
ios::sync_with_stdio(0);
cin.tie(0);
//read and write files
freopen("beads.in", "r", stdin);
freopen("beads.out", "w", stdout);
//get as input all the bead colors
int N; cin >> N;
char beads[N]; for(int i=0;i<N;i++) cin >> beads[i];
//the max amount of stuff we can get
int maxCount = INT_MIN;
//some helper variables we'll need later
int currCount = 0; int counter1 = 0; int counter2 = 0; char currColor = 'w';
for(int i=0;i<N;i++){
//set counter1 and counter2 both to 0
counter1 = 0; counter2 = 0;
//the iterator
int j;
//First loop - forwards
//---------------------
j = i;
currColor = beads[i];
while(beads[j]==currColor || beads[j]=='w'){
if(currColor == 'w' && beads[j] != 'w') currColor = beads[j];
if(j==N-1) j=0;
else j++;
counter1++;
if(counter1 > N) break;
}
//Second loop - backwards
//-----------------------
j = (i>0) ? i-1 : N-1;
currColor = (i>0) ? beads[i-1] : beads[N-1];
while(beads[j]==currColor || beads[j]=='w'){
if(currColor == 'w' && beads[j] != 'w') currColor = beads[j];
if(j==0) j=N-1;
else j--;
counter2++;
if(counter2 > N) break;
}
//get the current count and get max value
currCount = counter1 + counter2;
maxCount = max(currCount,maxCount);
}
if(maxCount > N) cout << N;
else cout << maxCount;
cout << "\n";
return 0;
}
For your code, I fixed it up a bit. But there is no guarantee that it will work for all cases. The reason why 74 is the correct answer is because you are allow to have the color change from "r to b" or "b to r" one. So for example, with "rrrrbbb", you can grab all 7 beads. Now when it come "w", it could be either "r" or "b". Thus, with this string.
rwrwrwrwrwrwrwrwrwrwrwrwbwrwbwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwr
You can grab either b and the w behind it or in front of it but not the r. If you grab the first b then neither can you grab the second b. Thus, if grabbing either way, you will have left 1r, 1w, and 1b.
For why your code did not work, you did not allow the color to change from r to b for one. I fixed your forward code, test your code, but I have not test your backward code. It will work for the string below, but who know about all the other strings.
With this, I give you a spoiler code. For my code, it passed the submission but I am still trying to efficient it so I may modify it in the future.
Nonetheless, for my code. Think of the end of your string like a portal. One you step into the portal. You will appear at the beginning. Nonetheless, if you step through the portal one and then reaching to the space where you started, the portal is gone. Thus, that mean you are done.
Also, remember, what you can get searching backward, can also be obtain going forward with some help from a teleportation device.
Update:
Although the teleportation code looked cool, it is not the most efficient code. I came up with a second solution to solve the problem. That is to compress the beads into blocks and add the blocks of beads together. In that method, I grouped the bead to only two types 'r' and 'b'. For the 'w' beads if they preceding a block, their count will not be added to that block but we keep track of their count. However, if they are succeeding a block they will be added into a block. For the 'w' bead that are like rwr or bbwwbb, they become the count of that block or simply we converted them to r or b, respectively. In the end we only have to calculate the count of each beads block that are next to each other. Thus, saving the nested loop. That is spoiler code number 2. Spoiler 2 also passed submission. It looked like c code but spoiler 2 can be submitted as either c or cpp code.
Your Code With Some Fixed:
#include <bits/stdc++.h>
using namespace std;
int main(){
//For faster I/O
ios::sync_with_stdio(0);
cin.tie(0);
//read and write files
freopen("beads.in", "r", stdin);
freopen("beads.out", "w", stdout);
//get as input all the bead colors
int N; cin >> N;
char beads[N]; for(int i=0;i<N;i++) cin >> beads[i];
//the max amount of stuff we can get
int maxCount = INT_MIN;
//some helper variables we'll need later
int currCount = 0; int counter1 = 0; int counter2 = 0; char currColor = 'w';
for(int i=0;i<N;i++){
//set counter1 and counter2 both to 0
counter1 = 0; counter2 = 0;
//the iterator
int j;
bool changeOne = 0;
//First loop - forwards
//---------------------
j = i;
currColor = beads[i];
while(1){
// The color allow to change one
// For example
// rrrrbbbb is perfectly 8 beads you can get.
// Nonetheless bbbrrrrbr you can only get the first 3b and 4 r to make the longesth.
// Now when it come to w, it can be either. Thus with this string below.
// rwrwrwrwrwrwrwrwrwrwrwrwbwrwbwrw
// you can get either one b with the w behind it or one b with the w before it.
if ( beads[j] != currColor ){
if ( beads[j] != 'w' && changeOne ) break;
// if we start with 'w'
// and the color haven't change
// we better change it
if ( currColor == 'w' )
currColor = beads[j];
else
changeOne = true;
}
if(currColor == 'w' && beads[j] != 'w') currColor = beads[j];
if(j==N-1) j=0;
else j++;
counter1++;
if(counter1 == N) break;
}
//Second loop - backwards
//-----------------------
j = (i>0) ? i-1 : N-1;
currColor = (i>0) ? beads[i-1] : beads[N-1];
while(beads[j]==currColor || beads[j]=='w'){
if(currColor == 'w' && beads[j] != 'w') currColor = beads[j];
if(j==0) j=N-1;
else j--;
counter2++;
if(counter2 == N) break;
}
//get the current count and get max value
currCount = counter1 + counter2;
maxCount = max(currCount,maxCount);
}
if(maxCount > N) cout << N;
else cout << maxCount;
cout << "\n";
return 0;
}
Spoiler Code:
#include <fstream>
using namespace std;
int main () {
ifstream fin("beads.in");
ofstream fout("beads.out");
int totalBeads, len, thisCount, j;
int maxL = 0,
changeOne = 0;
// Read into char array instead of
// string for faster performance
char beads[350], thisChar, lookFor;
fin >> len;
fin >> beads;
// lastIndex is made so that this
// doesn't have to be computed for every loop.
const int lastIndex = len - 1;
for (int i = 0; i < len; i++ ){
thisCount = 1;
lookFor = beads[i];
j = i + 1;
while(1) {
// If we reach the end
// we start again at the beginning.
if ( j > lastIndex ) j = 0;
// If we reach where we use to be
// we are done for this nested loop
if ( j == i ) goto makeLength;
thisChar = beads[j];
if ( thisChar != lookFor ){
if ( lookFor == 'w' ){
lookFor = thisChar;
} else if ( thisChar != 'w' ){
lookFor = thisChar;
// If bead already change between
// r and b one we are done.
if ( changeOne == 1 ){
makeLength:
if ( thisCount > maxL ) maxL = thisCount;
changeOne = 0;
break;
}
// We are allow one change.
changeOne++;
}
}
thisCount++;
j++;
}
}
fout << maxL << endl;
return 0;
}
Spoiler 2 (Block Compressing):
#include <stdio.h>
typedef struct beadBlock{
int preW;
int count;
char type;
} beadBlock;
int main () {
FILE *fin = fopen ("beads.in", "r");
FILE *fout = fopen ("beads.out", "w");
int len;
int maxL = 0,
thisCount = 0,
wCount = 0,
pos = 0,
blockLen = 0;
// For this algorithm we compress the beads to blocks of beads.
// At worst there is the same amount of block as bead.
// For example, rbrbrbrb.
// We never need to keep track of the white beads that are
// behind a block. This, method, included their count into the
// a block count.
beadBlock blocks[351];
char beads[351], thisChar, lookFor;
fscanf(fin, "%d", &len);
fscanf(fin, "%s", beads);
// Discard all white beads at the beginning of the string.
while ( beads[pos] == 'w' ){
pos++;
wCount++;
}
// If pos == len, it is all w
// lookFor's value can be of anything
// because it won't be used.
if ( pos != len ) lookFor = beads[pos];
blocks[blockLen].preW = wCount;
for ( ; pos < len; pos++ ){
thisChar = beads[pos];
// If it is w we just increase
// the white count.
if ( thisChar == 'w' ) {
wCount++;
} else {
if ( thisChar != lookFor ){
blocks[blockLen].count = thisCount;
blocks[blockLen].type = lookFor;
blockLen++;
// Preparing the wCount for next block.
blocks[blockLen].preW = wCount;
thisCount = 0;
lookFor = thisChar;
}
// For anything that is not a 'w', we turn wCount to zero.
wCount = 0;
}
thisCount++;
}
blocks[blockLen].count = thisCount;
blocks[blockLen].type = lookFor;
blockLen++;
if ( blockLen < 3 ){
// If there are less than 3 block, it is easy.
// If there is just www, the w count will be added
// by doing block[0].preW.
maxL = blocks[0].preW;
maxL += blocks[0].count;
if (blockLen == 2) maxL += blocks[1].count;
} else {
int lastBlock = blockLen - 1;
// If there were more than 3 blocks,
// we calculate the count of the border blocks first
// and use the length of the higher count.
// If block[0] and block[last] are the same type
// we need to add an additional block.
if ( blocks[0].type == blocks[lastBlock].type){
int maxL2;
// block[last] + block[0] + block[1]
// block[last] + block[last - 1] + block[0]
maxL = blocks[lastBlock].count;
// When calculating a block, any white
// succeeding a block will be inclusive in the count of
// that block but not the white beads proceeding it.
// Thus, when adding two block together that are next
// to each other we do not need to add the
// posW value to the count. However, we have to add preW
// to the value of the block that does not
// have any other block on the left of it.
maxL += blocks[lastBlock].preW;
maxL += blocks[0].preW;
maxL += blocks[0].count;
maxL += blocks[1].count;
maxL2 = blocks[lastBlock - 1].preW;
maxL2 += blocks[lastBlock - 1].count;
maxL2 += blocks[lastBlock].count;
maxL2 += blocks[0].preW;
maxL2 += blocks[0].count;
if ( maxL2 > maxL) maxL = maxL2;
} else {
// If last block and first block are not the same type,
// just add block[last] to block[0]
maxL = blocks[lastBlock].preW;
maxL += blocks[lastBlock].count;
maxL += blocks[0].preW;
maxL += blocks[0].count;
}
// Then we loop.to calculate the length of all
// blocks that are next to each other.
for ( int i = 0; i < lastBlock; i++ ){
// Reusing this count.
thisCount = blocks[i].preW;
thisCount += blocks[i].count;
thisCount += blocks[i+1].count;
if ( thisCount > maxL ) maxL = thisCount;
}
}
fprintf(fout, "%d\n", maxL );
return 0;
}
I have solved this problem myself using C++ (my solution is available here).
I won't give debug your code for you, but I'll give you some hints of how to approach this problem.
You have the right idea that you need to traverse the necklace both forwards and backwards. It might be helpful to create two helper functions that traverse cyclically to the left and to the right (use modular arithmetic)
But where do you start collecting beads from? Just try all possible starting points. Since the bounds on N are relatively small, in your main, you can just have another for-loop that runs through i = 0, 1, ... N - 1, where i denotes the starting point of your bead-collection process. Of course this means that your two helper functions will need to take in a starting index from which beads will begin to be collected.
Now what exactly do the left/right traversal functions do? Given a start index and the beads, we should first determine which bead we're collecting (so increment the starting point until we're no longer at a white bead). Then we can just use another while-loop and increment count until we cannot go any further. Be careful for infinite loops here (consider a necklace with all beads of the same color).
Let me know if you have any questions.
I have a task to print maximum int of matrix second line.
Example input:
3 2 (n, m)
-1 -2 <- 1 line
4 5 <- 2 line
2 6 <- 3 line
Max int in second line is 5. My program prints it. But if second line would be -100 -150, it not works. Sure it is because I have max = 0, but I don't know how to use it properly. I'm a student. Thanks in advance.
It is my code:
#include <iostream>
using namespace std;
int main() {
int n, m, max = 0;
cin >> n >> m;
int matrix[10][10];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> matrix[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[1][j] > max) {
max = matrix[1][j];
}
}
}
if (max == 0 || n == 1) {
cout << "No";
} else {
cout << max;
}
}
And code works pretty good, unless there are negative numbers in second line
You are correct to suspect max = 0;. Why is that a problem? Well, first, perhaps you should try to explain to your rubber duck why it is correct. As you try to do so, you are likely to express an intent along the lines of "this value will not make it through the checks" or "this value will be replaced in the first iteration of the loop". Why? "Because matrix[1][j] > max will be true, so... Hold on, wasn't the problem when matrix[1][j] > 0 is false? So when max is 0, um... problem?"
The overall strategy is valid, but there is a requirement that max be initialized to a low enough value. There are two common strategies I can think of at the moment.
Use a value that is as low as possible for the type you are using. That is:
int max = std::numeric_limits<int>::lowest();
Use the value from the first iteration of the loop. No need to provide a value that is just going to be replaced anyway. There are some caveats for this, though. The most relevant for your example can be expressed as a question: what if there is no first iteration? (Perhaps there is only one row? Perhaps there are no columns?) Also, you would need to initialize max between your loops, after the matrix has been given values.
int max = (n > 1 && m > 0) ? matrix[1][0] : /* what value do you want here? */;
I need your help with this problem. What I want to know is how to output of a loop based on the input.
Let's say we have a program that should measure if a triangle is right or not based on the inputs of the user. The input could be something like this:
6 8 10
25 52 60
5 12 13
Using the Pythagoras formula, we can determine if a triangle is or not right
C^2=a^2+b^2
Now, with the numbers provided, the output should be:
right
wrong
right
My question is..how can I do the calculation and check if it's right or not but format the output with the same order as the input?
This is what I've tried :
#include <iostream>
#include <cmath>
using namespace std;
int rightt;
int wrong;
int main()
{
double a = 0, b = 0, c = 0;
double formula = 0;
for (int i = 0; i < 1;)
{
cin >> a >> b >> c;
formula = pow(a, 2) + pow(b, 2);
if (formula == pow(c, 2) && formula != 0)
{
//cout << "Right";
rightt = rightt + 1;
}
if (formula != pow(c, 2) && formula != 0)
{
//cout << "Wrong";
wrong = wrong + 1;
}
if (a == 0 && b == 0 && c == 0)
{
i = 1;
cout << "\n";
while (rightt > 0)
{
cout << "\n" << "Right";
rightt = rightt - 1;
}
while (wrong > 0)
{
cout << "\n" << "Wrong";
wrong = wrong - 1;
}
}
}
system("pause");
}
But my output is not as I desired. The output is first set the right, and then the wrong ones. Thanks, and I hope you understand my problem.
EDIT:
I need to have the output after the 0 0 0 is reached and not before. So If I left the commented sections , the output will be Number-output-Number-output , and what I need is to allow users to enter all numbers and tell the software that he finishes when he enters 0 0 0 , and after that give the output based on the order.
Let's imagine this input :
6 8 10 >> this is right
25 52 60 >> This is wrong
5 12 13 >> This is right
0 0 0 >> This is the values used to end the inputs
Output should be
right
wrong
right
I think that rather than counting the number of right answers and wrong answers, you can STORE all of your answers IN ORDER, in an vector. Once you are done storing all your answers, you can just loop through the answers, and print them out one by one.
If you have not learned about vectors yet, the concept is simple... you have an array like collection of data. "push_back" always tacks the data to the end of the collection of data. So if your first answer was wrong, then right, then right, first you would push_back(wrong)...resulting in a collection of [wrong]. Then you would push_back(right) resulting in a collection of [wrong, right]. Again you would push_back(right) so your final vector would be a collection in the order of [wrong, right, right]
Now you just need to loop through your collection to print out the data. The "iter" is a pointer to each spot in your list. To get the "contents of each spot" you dereference, by saying (*iter) which will provide the string result values.
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
int main()
{
double a = 0, b = 0, c = 0;
double formula = 0;
int numberOfResults = 0;
int currentIndex = 0;
vector<string> answers;
for (int i = 0; i < 1;)
{
cout << "Enter the number of attempts: " << "\n";
cin >> numberOfResults;
string results[numberOfResults];
cout << "Enter a b and c" << "\n";
cin >> a >> b >> c;
formula = pow(a, 2) + pow(b, 2);
if (formula == pow(c, 2) && formula != 0)
{
results[currentIndex] = "Right";
answers.push_back("Right");
}
if (formula != pow(c, 2) && formula != 0)
{
results[currentIndex] = "Wrong";
answers.push_back("Wrong");
}
if (a == 0 && b == 0 && c == 0 || currentIndex == numberOfResults-1)
{
for (int j = 0; j < numberOfResults; j++){
cout << "\n" << results[j];
}
for(auto iter = answers.begin(); iter != answers.end(); ++iter){
cout << "\n" << (*iter);
}
return 0;
}
}
system("pause");
}
I have some code for the game of life that takes the users input and displays that input as to which cells they entered as alive, but it always prints a row of four * no matter what. I've messed around with changing things a lot of different ways, but it either still prints the same thing, or doesn't display anything at all. I've done searching around multiple forums and websites, but every code i find is done completely different, which is something i would expect (including code from stackoverflow).
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
#include <memory.h>
int main ()
{
const long MaxCols (10);
const long MaxRows (10);
const time_t WaitTime (3);
bool Board [MaxRows + 2] [MaxCols + 2];
long CurrCol;
long CurrRow;
time_t StopTime;
long Generation;
long OriginalArray[MaxRows][MaxCols];
long NewArray[MaxRows][MaxCols];
long Neighbors;
do
{
cout << "Enter a row and col for the living cell: ";
cin >> CurrRow >> CurrCol;
} while (CurrRow != 0 && CurrCol != 0);
for (Generation = 1; ; Generation++)
{
//Display the current generation on the board
system("cls");
cout << "\tCurrent Generation: " << Generation << endl;
for (CurrRow = 1; CurrRow <= MaxRows; CurrRow++)
{
for (CurrCol = 1; CurrCol <= MaxCols; CurrCol++)
cout << (Board [CurrRow + 2] [CurrCol + 2] ? ' ' : '*');
cout << endl;
}
//Loop to determine nieghbors
for(CurrRow=1; CurrRow <= MaxRows + 2; CurrRow++)
{
cout << endl;
for (CurrCol = 1; CurrCol <= MaxCols + 2; CurrCol++)
{
if (OriginalArray[CurrRow][CurrCol] == '*')
{
Neighbors = (OriginalArray, CurrRow, CurrCol);
if (Neighbors != 3 || Neighbors != 4 )
NewArray[CurrRow][CurrCol] = ' ';
else
NewArray[CurrRow][CurrCol] = '*';
}
else
{
Neighbors = (OriginalArray, CurrRow, CurrCol);
if (Neighbors != 2 || Neighbors != 3 )
NewArray[CurrRow][CurrCol] = ' ';
else
NewArray[CurrRow][CurrCol] = '*';
}
cout << "Touch any key to halt the program";
StopTime = time(0) + WaitTime; // time(0) gives the number of seconds since Jan 1, 1970
while (time (0) < StopTime) // keep looping until the current time catches the stop time
if (_kbhit()) //true if the user has hit a key, false if not hit a key
{
cout << "\nBye" << endl;
exit(0);
}
else;
}
}
}
}
Messing around is no way to debug a program. When it doesn't behave as you expect your first step should be to try to understand why. By making what, at your level of experience, will basically be random changes to your code you will just make things worse. As Oli mentioned a debugger is the best tool for this. You should learn how to use yours.
Looking at the code there are probably lots of errors but one error jumps out at me which is this
Neighbors = (OriginalArray, CurrRow, CurrCol);
I've no idea why you think this will count the number of neighbours but trust me it doesn't. I suppose you took a guess and then when the compiler didn't complain you assumed the guess was right. I'm afraid not.
So that's the bit to concentrate on first. You need some new code to count the number of live neighbours. Have a think about that.
There's no code above to enter values into Board. Here some code to do that. It's correct as far as it goes, but that doesn't mean it will work with the rest of your code which needs a lot of work.
// baord uses false for dead cells and true for living cells
bool Board [MaxRows + 2] [MaxCols + 2];
// initially make the whole board dead
for (int i = 0; i < MaxRows + 2; ++i)
for (int j = 0; j < MaxCols + 2; ++j)
Baord[i][j] = false;
// now ask the user for some live cells
for (;;)
{
cout << "Enter a row and col for the living cell (0 0 to quit): ";
int i, j;
cin >> i >> j;
if (i == 0 && j == 0)
break; // user entered 0 0 so quit loop
Board[i][j] = true; // set position i,j to live
}
The two parts that were missing from your code were initially setting the whole Board to dead, and secondly once you have got the coordinates for a live cell from the user you did nothing to set that cell to live.
One other thing that's confusing me about your code is that you have different size boards
bool Board [MaxRows + 2] [MaxCols + 2];
long OriginalArray[MaxRows][MaxCols];
long NewArray[MaxRows][MaxCols];
Why does Board have + 2 and the others don't. That makes no sense to me.
I am attempting to make a maze-solver using a Breadth-first search, and mark the shortest path using a character '*'
The maze is actually just a bunch of text. The maze consists of an n x n grid, consisting of "#" symbols that are walls, and periods "." representing the walkable area/paths. An 'S' denotes start, 'F' is finish. Right now, this function does not seem to be finding the solution (it thinks it has the solution even when one is impossible). I am checking the four neighbors, and if they are 'unfound' (-1) they are added to the queue to be processed.
The maze works on several mazes, but not on this one:
...###.#....
##.#...####.
...#.#.#....
#.####.####.
#F..#..#.##.
###.#....#S.
#.#.####.##.
....#.#...#.
.####.#.#.#.
........#...
What could be missing in my logic?
int mazeSolver(char *maze, int rows, int cols)
{
int start = 0;
int finish = 0;
for (int i=0;i<rows*cols;i++) {
if (maze[i] == 'S') { start=i; }
if (maze[i] == 'F') { finish=i; }
}
if (finish==0 || start==0) { return -1; }
char* bfsq;
bfsq = new char[rows*cols]; //initialize queue array
int head = 0;
int tail = 0;
bool solved = false;
char* prd;
prd = new char[rows*cols]; //initialize predecessor array
for (int i=0;i<rows*cols;i++) {
prd[i] = -1;
}
prd[start] = -2; //set the start location
bfsq[tail] = start;
tail++;
int delta[] = {-cols,-1,cols,+1}; // North, West, South, East neighbors
while(tail>head) {
int front = bfsq[head];
head++;
for (int i=0; i<4; i++) {
int neighbor = front+delta[i];
if (neighbor/cols < 0 || neighbor/cols >= rows || neighbor%cols < 0 || neighbor%cols >= cols) {
continue;
}
if (prd[neighbor] == -1 && maze[neighbor]!='#') {
prd[neighbor] = front;
bfsq[tail] = neighbor;
tail++;
if (maze[neighbor] == 'F') { solved = true; }
}
}
}
if (solved == true) {
int previous = finish;
while (previous != start) {
maze[previous] = '*';
previous = prd[previous];
}
maze[finish] = 'F';
return 1;
}
else { return 0; }
delete [] prd;
delete [] bfsq;
}
Iterating through neighbours can be significantly simplified(I know this is somewhat similar to what kobra suggests but it can be improved further). I use a moves array defining the x and y delta of the given move like so:
int moves[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
Please note that not only tis lists all the possible moves from a given cell but it also lists them in clockwise direction which is useful for some problems.
Now to traverse the array I use a std::queue<pair<int,int> > This way the current position is defined by the pair of coordinates corresponding to it. Here is how I cycle through the neighbours of a gien cell c:
pair<int,int> c;
for (int l = 0;l < 4/*size of moves*/;++l){
int ti = c.first + moves[l][0];
int tj = c.second + moves[l][1];
if (ti < 0 || ti >= n || tj < 0 || tj >= m) {
// This move goes out of the field
continue;
}
// Do something.
}
I know this code is not really related to your code, but as I am teaching this kind of problems trust me a lot of students were really thankful when I showed them this approach.
Now back to your question - you need to start from the end position and use prd array to find its parent, then find its parent's parent and so on until you reach a cell with negative parent. What you do instead considers all the visited cells and some of them are not on the shortest path from S to F.
You can break once you set solved = true this will optimize the algorithm a bit.
I personally think you always find a solution because you have no checks for falling off the field. (the if (ti < 0 || ti >= n || tj < 0 || tj >= m) bit in my code).
Hope this helps you and gives you some tips how to improve your coding.
A few comments:
You can use queue container in c++, its much more easier in use
In this task you can write something like that:
int delta[] = {-1, cols, 1 -cols};
And then you simple can iterate through all four sides, you shouldn't copy-paste the same code.
You will have problems with boundaries of your array. Because you are not checking it.
When you have founded finish you should break from cycle
And in last cycle you have an error. It will print * in all cells in which you have been (not only in the optimal way). It should look:
while (finish != start)
{
maze[finish] = '*';
finish = prd[finish];
}
maze[start] = '*';
And of course this cycle should in the last if, because you don't know at that moment have you reach end or not
PS And its better to clear memory which you have allocate in function