Knight tour all answers in c++ - c++

For knight tour problem, I came up with this answer; however, it just prints one answer. I don't know how to print all answers. I know I should change the output of find tour into void to avoid finishing but I don't know how. Can anyone modify it?
#include <iostream>
using namespace std;
const int ROW_COUNT = 6;
const int COL_COUNT = 6;
const int POSSIBLE_MOVES = 8;
int row_delta[POSSIBLE_MOVES] = {2, 1, -1, -2, -2, -1, 1, 2};
int col_delta[POSSIBLE_MOVES] = {-1, -2, -2, -1, 1, 2, 2, 1};
int board[ROW_COUNT][COL_COUNT];
void print_board() {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COL_COUNT; j++) {
if (board[i][j] < 10)
cout << ' ';
cout << board[i][j] << ' ';
}
cout << endl;
}
cin.get();
}
bool find_tour(int move_no, int current_row, int current_col) {
// uncomment the following two lines for debugging:
//cout << move_no << endl;
//print_board();
if (move_no == ROW_COUNT * COL_COUNT)
return true;
for (int move = 0; move < POSSIBLE_MOVES; move++) {
int new_row = current_row + row_delta[move];
int new_col = current_col + col_delta[move];
if (new_row < 0 || new_row >= ROW_COUNT || new_col < 0 || new_col >= COL_COUNT)
continue;
if (board[new_row][new_col] != 0)
continue;
board[new_row][new_col] = move_no + 1;
if (find_tour(move_no + 1, new_row, new_col))
return true;
board[new_row][new_col] = 0;
}
return false;
}
void solve(int init_row, int init_col) {
for (int row = 0; row < ROW_COUNT; row++)
for (int col = 0; col < COL_COUNT; col++)
board[row][col] = 0;
board[init_row][init_col] = 1;
if (find_tour(1, init_row, init_col))
print_board();
else
cout << "Failed to find a tour!\n";
}
int main() {
solve(2, 3);
}

Following from my comment, this code should work:
#include <iostream>
using namespace std;
const int ROW_COUNT = 6;
const int COL_COUNT = 6;
const int POSSIBLE_MOVES = 8;
int row_delta[POSSIBLE_MOVES] = {2, 1, -1, -2, -2, -1, 1, 2};
int col_delta[POSSIBLE_MOVES] = {-1, -2, -2, -1, 1, 2, 2, 1};
int board[ROW_COUNT][COL_COUNT];
void print_board() {
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < COL_COUNT; j++) {
if (board[i][j] < 10)
cout << ' ';
cout << board[i][j] << ' ';
}
cout << endl;
}
cin.get();
}
find_tour(int move_no, int current_row, int current_col) {
// uncomment the following two lines for debugging:
//cout << move_no << endl;
//print_board();
if (move_no == ROW_COUNT * COL_COUNT)
{
print_board();
return;
}
for (int move = 0; move < POSSIBLE_MOVES; move++) {
int new_row = current_row + row_delta[move];
int new_col = current_col + col_delta[move];
if (new_row < 0 || new_row >= ROW_COUNT || new_col < 0 || new_col >= COL_COUNT)
continue;
if (board[new_row][new_col] != 0)
continue;
board[new_row][new_col] = move_no + 1;
find_tour(move_no + 1, new_row, new_col);
board[new_row][new_col] = 0;
}
}
void solve(int init_row, int init_col) {
for (int row = 0; row < ROW_COUNT; row++)
for (int col = 0; col < COL_COUNT; col++)
board[row][col] = 0;
board[init_row][init_col] = 1;
find_tour(1, init_row, init_col);
}
int main() {
solve(2, 3);
}

Related

Error when traversing the matrix in a spiral, starting from the central element [duplicate]

This question already has answers here:
Print 2-D Array in clockwise expanding spiral from center
(4 answers)
Closed 2 years ago.
What is the error in the loops. For example, with a 4x4 matrix, starting at element 13 of the array new_matrix[13] gives incorrect values. With other dimensions matrices the same error.
int *helix_center (int** matrix, int size) {
int* new_matrix = new int[size * size];
int count = 0;
int step = 1;
int sup_var = size / 2;
int sup_var_2 = sup_var;
new_matrix[count] = matrix[sup_var][sup_var_2];
count++;
while( step < size ) {
for (int j = 0; ((j < step) && (step < size)); j++) {
if (sup_var_2 != 0)
new_matrix[count] = matrix[sup_var][--sup_var_2];
count++;
}
for (int j = 0; ((j < step) && (step < size)); j++) {
if(sup_var != 0)
new_matrix[count] = matrix[--sup_var][sup_var_2];
count++;
}
step++;
for (int j = 0; ((j < step) && (step < size)); j++) {
new_matrix[count] = matrix[sup_var][++sup_var_2];
count++;
}
for (int j = 0; ((j < step) && (step < size)); j++) {
new_matrix[count] = matrix[++sup_var][sup_var_2];
count++;
}
step++;
}
return new_matrix;
}
Tried to reproduce it, added some simple main with additional prints:
#include <iostream>
int* helix_center(int matrix[4][4], int size)
{
int* new_matrix = new int[size * size];
int count = 0;
int step = 1;
int sup_var = size / 2;
int sup_var_2 = sup_var;
new_matrix[count] = matrix[sup_var][sup_var_2];
std::cout << count << std::endl;
count++;
while (step < size) {
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
if (sup_var_2 != 0)
new_matrix[count] = matrix[sup_var][--sup_var_2];
count++;
}
std::cout << "=====" << std::endl;
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
if (sup_var != 0)
new_matrix[count] = matrix[--sup_var][sup_var_2];
count++;
}
std::cout << "=====" << std::endl;
step++;
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
new_matrix[count] = matrix[sup_var][++sup_var_2];
count++;
}
std::cout << "=====" << std::endl;
for (int j = 0; ((j < step) && (step < size)); j++) {
std::cout << count << std::endl;
new_matrix[count] = matrix[++sup_var][sup_var_2];
count++;
}
step++;
}
return new_matrix;
}
int main()
{
int matrix[4][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
int* output = helix_center(matrix, 4);
std::cout << output[13] << std::endl;
return 0;
}
Code yields the following:
0
1
=====
2
=====
3
4
=====
5
6
7
8
9
=====
10
11
12
=====
=====
1414422387
So, as you can see, we never go past 12, thus these indices are not being initialized. Quite a lot going on in your code, kinda hard to track counter's changes.
Here's a great implementation of what you're trying to do:
https://stackoverflow.com/a/33701500/5430833
Tweaked it a bit so instead of printing, it puts values to the output buffer:
#include <iostream>
#include <cmath>
#include <vector>
int* print_spiral (int** matrix, int size)
{
int* new_matrix = new int[size * size];
int x = 0; // current position; x
int y = 0; // current position; y
int d = 0; // current direction; 0=RIGHT, 1=DOWN, 2=LEFT, 3=UP
int c = 0; // counter
int s = 1; // chain size
// starting point
x = ((int)floor(size/2.0))-1;
y = ((int)floor(size/2.0))-1;
for (int k=1; k<=(size-1); k++)
{
for (int j=0; j<(k<(size-1)?2:3); j++)
{
for (int i=0; i<s; i++)
{
new_matrix[c] = matrix[x][y];
c++;
switch (d)
{
case 0: y = y + 1; break;
case 1: x = x + 1; break;
case 2: y = y - 1; break;
case 3: x = x - 1; break;
}
}
d = (d+1)%4;
}
s = s + 1;
}
return new_matrix;
}
int main()
{
std::vector<std::vector<int>> v{ { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
int **p = new int *[v.size()];
for ( size_t i = 0; i < v.size(); i++ ) p[i] = v[i].data();
int* output = print_spiral(p, 4);
for(int i = 0; i < 16; i++) {
std::cout << output[i] << std::endl;
}
return 0;
}
Which yields the following:
6
7
11
10
9
5
1
2
3
4
8
12
16
15
14
0
Which is what you expect, I believe.

reason for incorrect output on coding correct logic?

i am solving this question on leetcode:
my strategy to solve this is:
run dfs for each cell index (x,y) on each dfs call check
if cell is a destination cell accordingly set the flags
if both flags are true then add this cell to "ans" vector else carry on with the next dfs
my code:
#include <iostream>
using namespace std;
#include <vector>
class Solution {
public:
void psUtil(vector<vector<int> >&mat, int x, int y, int m, int n, int &isP, int &isA, vector<vector<int> >&vis, vector<vector<int> >&ans)
{
//check dstinations
if(x == 0 || y == 0)
{
//cout << "P true" << " x and y are " << x << y << endl;
isP = 1;
}
if(x == m-1 || y == n-1)
{
//cout << "A true" << " x and y are " << x << y << endl;
isA = 1;
}
vector<int> cell(2);
cell[0] = x;
cell[1] = y;
// check both dst rched
if(isA && isP)
{
// append to ans
//cout << "ans = " << cell[0] << " " << cell[1] << endl;
ans.push_back(cell);
return;
}
// mark vis
vis.push_back(cell);
int X[] = {-1, 0, 1, 0};
int Y[] = {0, 1, 0, -1};
int x1, y1;
// check feasible neighbours
for(int i = 0; i < 4; ++i)
{
x1 = x + X[i];
y1 = y + Y[i];
if(x1 < 0 || y1 < 0 || x1 >= m || y1 >= n) continue;
//cout << "if(mat.at(x1).at(y1) <= mat.at(x).at(y))" << endl;
if(mat.at(x1).at(y1) <= mat.at(x).at(y))
{
vector<vector<int> > :: iterator it;
vector<int> cell1(2);
cell1[0] = x1;
cell1[1] = y1;
it = find(vis.begin(), vis.end(), cell1);
if(it != vis.end())
continue;
psUtil(mat, x1, y1, m, n, isP, isA, vis, ans);
if(isA && isP) return;
}
}
}
vector<vector<int> > pacificAtlantic(vector<vector<int> >& matrix)
{
// find dimensions
int m = matrix.size(); // rows
int n = matrix[0].size(); // cols
vector<vector<int> >ans;
// flags if rched destinations
int isP, isA;
isP = isA = 0;
// iterate for all indices
for(int x = 0; x < m; ++x)
{
for(int y = 0; y < n; ++y)
{
// visited nested vector
vector<vector<int> >vis;
psUtil(matrix, x, y, m, n, isP, isA, vis, ans);
isP = isA = 0;
}
}
return ans;
}
};
/*
int main()
{
vector<vector<int> > mat{ {1,2,2,3,5},
{3,2,3,4,4},
{2,4,5,3,1},
{6,7,1,4,5},
{5,1,1,2,4} };
Solution ob;
vector<vector<int> > ans;
ans = ob.pacificAtlantic(mat);
for(int i = 0; i < ans.size(); ++i)
{
for(int j = 0; j < ans[0].size(); ++j)
{
cout << ans[i][j] << " ";
}
cout << endl;
}
return 0;
}
*/
for the given sample input my output is:
0 4
1 4
0 3
2 4
4 0
4 2
4 0
and the correct output is suppose to be:
[[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
where is this program going wrong?
Your code is pretty hard to debug. Here is a working solution with depth first search and memoization, easy to understand:
#include <vector>
class Solution {
public:
static inline constexpr int direction_row[4] = {0, 1, -1, 0};
static inline constexpr int direction_col[4] = {1, 0, 0, -1};
inline std::vector<std::vector<int>> pacificAtlantic(const std::vector<std::vector<int>> &grid) {
std::vector<std::vector<int>> oceans = grid;
std::vector<std::vector<int>> water_flows;
const int row_length = oceans.size();
if (!row_length) {
return water_flows;
}
const int col_length = oceans[0].size();
std::vector<std::vector<bool>> pacific(row_length, std::vector<bool>(col_length, false));
std::vector<std::vector<bool>> atlantic(row_length, std::vector<bool>(col_length, false));
for (int row = 0; row < row_length; row++) {
depth_first_search(oceans, pacific, row, 0, INT_MIN);
depth_first_search(oceans, atlantic, row, col_length - 1, INT_MIN);
}
for (int col = 0; col < col_length; col++) {
depth_first_search(oceans, pacific, 0, col, INT_MIN);
depth_first_search(oceans, atlantic, row_length - 1, col, INT_MIN);
}
for (int row = 0; row < row_length; row++)
for (int col = 0; col < col_length; col++)
if (pacific[row][col] && atlantic[row][col]) {
water_flows.push_back({row, col});
}
return water_flows;
}
private:
static inline void depth_first_search(const std::vector<std::vector<int>> &oceans, std::vector<std::vector<bool>> &visited, const int row, const int col, const int height) {
if (row < 0 || row > oceans.size() - 1 || col < 0 || col > oceans[0].size() - 1 || visited[row][col]) {
return;
}
if (oceans[row][col] < height) {
return;
}
visited[row][col] = true;
for (int iter = 0; iter < 4; iter++) {
depth_first_search(oceans, visited, row + direction_row[iter], col + direction_col[iter], oceans[row][col]);
}
}
};
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis1, 2 in there.

How is uncommenting a cout line changing the final answer?

I have the following code
#include <bits/stdc++.h>
using namespace std;
int main() {
int r = 0, c = 0;
int best = 0;
cin >> r >> c;
int myGrid[r + 2][c + 2] = {};
for (int i = 1; i < r + 1; i++) {
for (int j = 1; j < c + 1; j++) {
cin >> myGrid[i][j];
}
}
bool stillIn = false;
int di[] = {-1,-1, -1, 0, 0, 1, 1, 1};
int dj[] = {-1,0, 1, -1, 1, -1, 0, 1};
for (int i = 1; i < r + 1; i++) {
for (int J = 1; J < c + 1; J++) {
stillIn = false;
for (int k = 0; k < 8; k++) {
// cout << myGrid[i][J] << " " << endl;
if (myGrid[i][J] == myGrid[di[k]][dj[k]]) {
stillIn = true;
}
}
if (stillIn == true) {
best = myGrid[i][J];
}
}
}
cout << best;
return 0;
}
If I run the code with the following input:
4 3
0 1 0
1 2 0
1 5 1
2 3 4
It prints 4. However, if I uncomment line 28, which is
// cout << myGrid[i][J] << " " << endl;
Then it gives me 1, which is the correct answer. Why is this happening!? How does using cout change the final answer?
Thanks in advance for any help.
You have undefined behavior(UB) because you are indexing out of bounds on this line
myGrid[di[k]][dj[k]]
because di and dj contain values of -1.
If you have UB, then anything can happen, such as a cout statement exisiting or not, changing the program in weird ways.
Also variable length arrays are not allowed in standard c++.

Two-Dimensional Array Searching Algorithm Optimisation

I have been given a "Sand box" of variable length and width. I've been given instructions to find a "shovel" of static size, which may be oriented either horizontally or vertically. I implement the following algorithm in order to search the least amount of times to find one valid location (one which corresponds to a "part of the object") in the grid:
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; j < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
In this case, the "Sand box" will be tested by the function as described below.
I completely recreate this scenario with a "Sand box" whose size is fixed (though easily manipulated) whose shovel is still randomly placed and oriented within the following code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
const int ROW = 12;
const int COL = 16;
char sandbox[ROW][COL];
bool probeSandBoxTwo(char c, int i);
void displayResults(int sCount, bool found, int x, int y);
void displaySandbox();
void displaySearchPattern();
void fillSandbox();
void placeShovel();
int main() {
fillSandbox();
placeShovel();
displaySandbox();
//define your variables here
bool found;
int nShift,
sCount,
shovelSize,
x,
y;
found = false;
nShift = 0;
shovelSize = 4;
sCount = 0;
for(int i = 0; i < ROW && !found; i++) {
for(int j = 0; j < COL && !found; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
x = i;
y = j + nShift;
sCount++;
cout << "Search conducted at (" << i << ", " << (j + nShift) << ")" << endl;
}
if(nShift >= shovelSize - 1 || nShift > ROW) {
nShift = 0;
} else {
nShift++;
}
}
displayResults(sCount, found, x, y);
displaySearchPattern();
}
bool probeSandBoxTwo(char c, int i) {
if(sandbox[c-'A'][i-1] == 'X') {
return true;
} else {
return false;
}
}
void displayResults(int sCount, bool found, int x, int y) {
cout << endl;
cout << "Total searches: " << sCount << endl;
cout << endl;
if(found) {
cout << "Shovel found at coordinates: (" << x << ", " << y << ")" << endl;
}
}
void displaySandbox() {
cout << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
cout << sandbox[i][j];
}
cout << endl;
}
cout << endl;
}
void displaySearchPattern() {
int nShift = 0;
int shovelSize = 4;
cout << endl << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
if(!((j + nShift) % shovelSize)) {
cout << 'o';
} else {
cout << '.';
}
}
if(nShift >= shovelSize - 1 || nShift > COL) {
nShift = 0;
} else {
nShift++;
}
cout << endl;
}
}
void fillSandbox() {
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COL; j++) {
sandbox[i][j] = '.';
}
}
}
void placeShovel() {
srand(time(NULL));
int shovelRow,
shovelCol,
shovelSize = 4;
if(rand() % 2) {
//horizontal
shovelRow = rand() % ROW + 1;
shovelCol = rand() % (COL - (shovelSize - 1)) + 1;
for(int i = shovelCol - 1; i < shovelSize + (shovelCol - 1); i++) {
sandbox[shovelRow - 1][i] = 'X';
}
} else {
//vertical
shovelRow = rand() % (ROW - (shovelSize - 1)) + 1;
shovelCol = rand() % COL + 1;
for(int i = shovelRow - 1; i < shovelSize + (shovelRow - 1); i++) {
sandbox[i][shovelCol - 1] = 'X';
}
}
}
In this code, I also graphically display the pattern (when run) with which my algorithm searches.
Is this truly the optimal search pattern for such a scenario, is my implementation correct, and if so, why might I be having incorrect results returned?
A given test driver reports the following results:
The source code for this result (and its test driver).
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; (j + nShift) < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
This corrects an error in the conditional portion of the for loop header which did not account for the index-shifting variable nShift.

How to implement bfs on a matrix?

I am having trouble implementing bfs on a matrix. It seems like my code only checks for children of the starting node.
My goal is to find shortest path from 'B' to 'H'. I also think that my code needs a lot of modification. Thank you in advance!
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
int bfs(int, int);
bool visited[100][100];
char matrica[100][100];
int m, n, d;
int main()
{
scanf("%d %d", &m, &n);
for(int i = 0;i < m;i++){
for(int j = 0; j < n; j++){
cin >> matrica[i][j];
visited[i][j] = false;
}
}
for(int i = 0;i < m;i++){
for(int j = 0; j < n; j++){
if(matrica[i][j] == 'B'){
bfs(i, j);
}
}
}
cout << endl << d;
return 0;
}
int gk[] = {1, 0, -1, 0};
int gr[] = {0, 1, 0, -1};
int bfs(int x, int y){
cout << endl;
queue<int>queue_x, queue_y;
int topx, topy, d=0;
//memset(visited, 0, sizeof visited);
visited[x][y] = true;
queue_x.push(x);
queue_y.push(y);
while(!queue_x.empty()){
topx = queue_x.front();
topy = queue_y.front();
queue_x.pop();
queue_y.pop();
if(matrica[topx][topy] == 'H'){
cout << endl << d << endl;
d++;
return d;
}
for(int i = 0; i < 4; i++){
x += gk[i];
y += gr[i];
if(visited[x][y] == false && matrica[x][y] != '#'){
visited[x][y] = true;
matrica[x][y] = '*';
queue_x.push(x);
queue_y.push(y);
d++;
//-------------
for(int i = 0; i < m;i++){
for(int j = 0; j < n;j++){
cout << matrica[i][j];
}
cout << endl;
}
//-------------
}
}
}
}
Input/Output:
Input:
5
5
#####
#..B#
#...#
#...#
###H#
Output:
#####
#..B#
#...#
#...#
###H#
0
The variables x and y
x += gk[i];
y += gr[i];
shouldn't "remember" their values from one iteration to the next.
Change these lines to
x = topx + gk[i];
y = topy + gr[i];