I am trying to solve the famous NQUEENS problem using backtracking in c++ using vectors and class. But it is giving correct result for some cases(for ex. 5) and for remaining(for ex. 4) it is showing "Solutuon doesn't exist".
My code is as follows:
Class declaration for storing rows and columns of queen position.
class position
{
public:
int r,c;
position(int r,int c)
{
this->r=r;
this->c=c;
}
};
The recursive function:
vector<position> positions;
bool solve(int n, int r)
{
if(r==n)
return true;
for (int c = 0; c < n; ++c)
{
bool safe=true;
for(int q=0;q<r;++q)
{
if (positions[q].c == c || positions[q].r - positions[q].c == r - c
|| positions[q].r + positions[q].c == r + c)
{
safe = false;
break;
}
}
if(safe)
{
position p(r,c);
positions.push_back(p);
if(solve(n,r+1))
return true;
}
}
return false;
}
and the driver function is as follows:
int main()
{
int n;
cin>>n;
if(!solve(n,0))
{
cout<<"Solution doesn't exist"<<endl;
return 0;
}
printboard(n);
return 0;
}
Please help me in resolving this.
if(solve(n,r+1))
return true;
else
positions.erase(positions.begin()+positions.size()-1);
If the solution for one cell doesn't exist then erase that cell from possible positions so that it avoids collisions.
Edit:-
Thank You Mr.Bo R for your correction.
Related
https://leetcode.com/problems/longest-increasing-subsequence/
This the link of the question which I tried to solve using recursion + memorization technique but not able to solve my testcases only pass only up to 4 is also I don't know that whether my approach is correct or not.
Below this line is the code I tried:
int lis( vector<int>& nums, int i, int n, int prev, vector<int>& ls){
if(i==n||n==0){
return 0;
}
if(ls[i]!=-1){
return 1 ;
}
lis(nums,i+1,n,prev,ls);
if(nums[i]>prev){
int num=1+lis(nums,i+1,n,nums[i],ls);
ls[num]=1;
return num;
}
return 0;
}
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n=nums.size();
int c;
vector<int> ls(n+1,-1);
lis(nums,0,n,INT_MIN,ls);
for(int i=n;i>=0;i--) {
if(ls[i]!=-1) {
c=i;
break;
}
else {
c=0;
}
}
if(nums.size()==0) {
return 0;
}
else {
if(c==0) {
return 0;
}
else {
return c;
}
}
}
};
I want to know how to apply recursion + memorization technique in this type of question. Everyone is teaching bottom up approach, not top down approach so it is hard to understand top down. So explain me how to solve this question?
Here is the code I have written:
#include<iostream>
using namespace std;
int puzzle[9][9]=
{
{0,5,0,0,6,2,7,0,0},
{0,0,0,0,0,0,1,0,2},
{7,0,9,3,0,0,0,0,0},
{3,0,0,0,8,0,0,0,0},
{0,8,0,7,0,9,0,2,0},
{0,0,0,0,5,0,0,0,7},
{0,0,0,0,0,6,2,0,8},
{2,0,6,0,0,0,0,0,0},
{0,0,3,4,2,0,0,9,0},
};//puzzle template
bool row_possible(int row,int number);//To find out whether a number is possible in the particular row
bool column_possible(int column,int number);//To find whether a number is possible in the particular column
bool square_possible(int row,int column,int number);//To find whether a number is possible in its square
bool possible(int row,int column,int number);//To find whether a number is possible in the given position
bool unassigned();//To check whether the puzzle has any unassigned spaces
void printSolution();//To print the final solution to the console
bool solve();//To solve the puzzle
int main()
{
if(solve())
printSolution();
else
cout<<"\nNo Solution";
return 0;
}
bool row_possible(int row,int number)
{
int m=0;
for(int column=0;column<9;column++)
{
if(puzzle[row-1][column]==number)
m++;
}
if(m!=0)
return false;
else
{
return true;
}
}
bool column_possible(int column,int number)
{
int m=0;
for(int row=0;row<9;row++)
{
if(puzzle[row][column-1]==number)
m++;
}
if (m!=0)
return false;
else
{
return true;
}
}
bool square_possible(int row,int column,int number)
{
int mod_x=(row-1)%3,mod_y=(column-1)%3;
int i=(row-1)-mod_x,j=(column-1)-mod_y;
int m=0;
int k=0;
int check_x=3,check_y=3;
for(k=0;check_x!=0;check_x--)
{
for(k=0;check_y!=0;check_y--)
{
if(puzzle[i][j]==number)
m++;
j++;
}
i++;
}
if(m!=0)
return false;
else
{
return true;
}
}
bool possible(int row,int column,int number)
{
if(row_possible(row,number)&&column_possible(column,number)&&square_possible(row,column,number))
return true;
else
{
return false;
}
}
bool unassigned()
{
int m=0;
for(int row=0;row<9;row++)
{
for(int column=0;column<9;column++)
{
if(puzzle[row][column]==0)
m++;
}
}
if(m>0)
return true;
else
{
return false;
}
}
void printSolution()
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
cout<<puzzle[i][j]<<" ";
}
cout<<"\n";
}
}
bool solve()
{
if(!unassigned())
return true;
for(int row=1;row<10;row++)
{
for(int column=1;column<10;column++)
{
for(int number=1;number<10;number++)
{
if(possible(row,column,number))
{
puzzle[row-1][column-1]=number;
if(solve())
return true;
puzzle[row-1][column-1]=0;
}
}
}
}
return false;
}
The debugger is throwing the error in:
int m=0;
int k=0;
int check_x=3,check_y=3;
It says Exception has occurred.
EXC_BAD_ACCESS.It also says that read memory is failed.
I dont understand what it says.Let me also know whether my program needs any improvements
Kindly help me.I am using Visual Studio Code on MacOS.Thank You
You can do a simple calculation on how long it would take for you to get an answer.
You have 55 open cells that you try 9 different numbers. This gives you 955 = 3 * 1052 tries.
If one try takes 1μs it will take ~ 9.6 * 1038 years to find a solution.
I have written a C++ program and that finds a solution of this sudoku in 30ms and my PC is not a very fast one (5 years old) and 10ms of this is used to print the solution to screen with printf
I am trying sort edges in Prim's Algorithm using STL and overloading operator () , But I am getting runtime error Invalid operator and Invalid Heap.
When I compile my code in CodeBlocks everything's working but Visual Studio 2015 displayed runtime errors. What should I do?
struct edge {
int cost;
int start;
int end;
};
struct sorting {
bool operator() (const edge &a, const edge &b)
{
if (a.cost<b.cost) return false;
else return true;
}
};
priority_queue < edge , vector <edge> , sorting> queue;
edge tree[1005];
int T[1000][1000];
int G[1005][1005];
bool ISIT[1005];
string STRINGS[1005];
int ID[40005];
int howmany = 0;
int howmanyneigh[1005];
void PRIM() {
int w = 1;
ISIT[w] = 1;
edge K;
howmany++;
for (int i = 0; i<howmanyneigh[w]; i++) {
K.start = w;
K.end = G[w][i];
K.cost = T[w][G[w][i]];
queue.push(K);
}
while (howmany<N)
edge b;
b = queue.top();
queue.pop();
while (ISIT[b.end]) {
b = queue.top();
queue.pop();
}
ISIT[b.end] = 1;
tree[howmany - 1] = b;
for (int i = 0; i<howmanyneigh[b.end]; i++) {
K.start = b.end;
K.end = G[b.end][i];
K.cost = T[b.end][G[b.end][i]];
queue.push(K);
}
howmany++;
}
}
It seems that you have a problem in your sorting comparator. This comparator should provide strict weak ordering. One of the requirements for strict weak ordering is that comp(a, a) == false. Change your sorting::operator() from
if (a.cost<b.cost) return false;
else return true;
to:
if (a.cost>b.cost) return true;
else return false;
or simply:
return a.cost > b.cost;
I'm interested in learning how to run Kruskal's algorithm on O(n log n) in c++. I have implemented the algorithm with a solution that runs on O(n^2), and the code for that is below.
I know that it should be possible to run Kruskal's on O(n log n), but I'm stymied as to how this can be done. I would appreciate any and all tips.
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
//sort by weight
bool sorting (vector<int> i, vector<int> j) {return i[2]<j[2];}
class Submap {
private:
set<int> finder;
public:
Submap(int x) {finder.insert(x);}
Submap(set<int> x) {finder = x;}
set<int> pointreturn() {return finder;}
//function to add new set to current tree
void add(set<int> np) {
finder.insert(np.begin(), np.end());
}
void add(int n) {
finder.insert(n);
}
int size() {return int(finder.size());}
//find function returns true if the value is not found
bool find(int x) {
if (finder.find(x) == finder.end())
return true;
else
return false;
}
};
class Map {
private:
vector<Submap> submaps;
public:
int find(int x) {
int finder = -1;
for(int i = 0; i < int(submaps.size()); i++) {
if(!submaps[i].find(x)) {
finder = i;
break;
}
}
return finder;
}
void newsubmap(int a, int b) {
set<int> nextset;
nextset.insert(a);
nextset.insert(b);
submaps.push_back(Submap(nextset));
}
void addendum(int a, int index) {
submaps[index].add(a);
}
Submap subfind(int i) {return submaps[i];}
void fuse(int index1, int index2) {
submaps[index1].add(submaps[index2].pointreturn());
vector<Submap> nextmaps;
for(int i = 0; i < int(submaps.size()); i++) {
if (i != index2)
nextmaps.push_back(submaps[i]);
}
submaps = nextmaps;
}
int size() {return submaps[0].size();}
};
Map kruskal (vector<vector<int>> &graph, int weight, int junct) {
//sort the graph
sort(graph.begin(), graph.end(), sorting);
Map currmap;
int usedweight = 0;
for(int i=0; i<graph.size(); i++) {
int a = currmap.find(graph[i][0]);
int b = currmap.find(graph[i][1]);
//the boolean expression here is false if both points are already in the same submap
if(a != b || a == -1) {
usedweight += graph[i][2];
//if neither point is in the map so far
if(a == -1 && b == -1) {
currmap.newsubmap(graph[i][0], graph[i][1]);
}
//if one point is in the map so far
else if (a != -1 && b == -1) {
currmap.addendum(graph[i][1], a);
}
else if (a == -1 && b != -1) {
currmap.addendum(graph[i][0], b);
}
//if both points are in the map, but different submaps
else {
currmap.fuse(a, b);
}
}
//if the first set in the map is spanning, the algorithm is done
if(currmap.size() == junct)
break;
}
return (currmap);
}
I am trying to solve Knight Tour Problem using recursive Backtracking. Can someone help me optimize my code. My code works till 6X6 board. . After N=7 it takes almost infinite time to solve .
Here is my code :
#include <iostream>
#include "genlib.h"
#include "grid.h"
#include "vector.h"
#include <iomanip>
const int NOT_VISITED = -1;
//Size of the board
const int N = 6;
const int N2 = N*N;
typedef Grid<int> chess;
struct position{
int row;
int col;
};
//Initializes the board and makes each and every
//square value as NOT_VISITED
void initializeBoard(chess &board)
{
for(int i=0;i<board.numRows();i++)
for(int j=0;j<board.numCols();j++)
board[i][j] = NOT_VISITED;
}
//Returns true if the square is visited;
bool visited(chess &board,position square)
{
return board[square.row][square.col ] != NOT_VISITED;
}
//Returns true if the givien position variable is outside the chess board
bool outsideChess(chess &board, position square)
{
if(square.row <board.numRows() && square.col <board.numCols() && square.row >=0 && square.col >=0)
return false;
return true;
}
void visitSquare(chess &board,position square,int count)
{
board[square.row] [square.col] = count;
}
void unVisitSquare(chess &board,position square)
{
board[square.row] [square.col] = NOT_VISITED;
}
position next(position square,int irow, int icol)
{
square.row += irow;
square.col += icol;
return square;
}
Vector<position> calulateNextSquare(chess board,position square)
{
Vector<position> list;
for(int i=-2;i<3;i=i+4)
{
for(int j=-1;j<2;j=j+2)
{
list.add(next(square,i,j));
list.add(next(square,j,i));
}
}
return list;
}
bool knightTour(chess &board,position square, int count)
{
//cout<<count<<endl;
//Base Case if the problem is solved;
if(count>N2)
return true;
if(outsideChess(board,square))
return false;
//return false if the square is already visited
if(visited(board,square))
return false;
visitSquare(board,square,count);
Vector<position> nextSquareList = calulateNextSquare(board,square);
for(int i=0;i<nextSquareList.size();i++)
if(knightTour(board, nextSquareList[i], count+1))
return true;
unVisitSquare(board,square);
return false;
}
void printChess(chess &board)
{
for(int i=0;i<board.numRows();i++)
{
for(int j=0;j<board.numCols();j++)
cout<<setw(4)<<board[i][j];
cout<<endl;
}
}
int main()
{
chess board(N,N);
initializeBoard(board);
position start;
start.row = 0; start.col = 0;
if(knightTour(board,start,1))
printChess(board);
else
cout<<"Not Possible";
return 0;
}
i am using Stanford 106B Libraries( grid is a 2 dimensional vector )
Visual studio 2008 Blank project with required library files https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0BwLe9NJT8IreNWU0N2M5MGUtY2UxZC00ZTY2LWE1YjQtMjgxYzAxMWE3OWU2&hl=en
I'd say, for a start, get rid of this:
Vector<position> nextSquareList = calulateNextSquare(board,square);
creating a Vector on each step will take a lot of time. You could either use an array (fixed sized, since you know there are 8 possible moves), or unroll the loop entirely. Compare with this version, similar to yours.
Some modifications I would like to suggest:
#include <iostream>
#include "genlib.h"
#include "grid.h"
#include "vector.h"
#include <iomanip>
const int NOT_VISITED = -1;
//Size of the board
const int N = 6;
const int N2 = N*N;
typedef int chess[N][N]; // <------------- HERE
struct position{
int row;
int col;
};
//Initializes the board and makes each and every
//square value as NOT_VISITED
void initializeBoard(chess &board)
{
for(int i=0;i<board.numRows();i++)
for(int j=0;j<board.numCols();j++)
board[i][j] = NOT_VISITED;
}
//Returns true if the square is visited;
bool visited(chess &board,position square)
{
return board[square.row][square.col ] != NOT_VISITED;
}
//Returns true if the givien position variable is outside the chess board
bool outsideChess(chess &board, position square)
{
if(square.row <board.numRows() && square.col <board.numCols() && square.row >=0 && square.col >=0)
return false;
return true;
}
void visitSquare(chess &board,position square,int count)
{
board[square.row] [square.col] = count;
}
void unVisitSquare(chess &board,position square)
{
board[square.row] [square.col] = NOT_VISITED;
}
position next(position square,int irow, int icol)
{
square.row += irow;
square.col += icol;
return square;
}
void calulateNextSquare(chess board,position square, Vector<position>& list) // <------------- HERE
{
// ------------- HERE
//Also, change this part to add only unvisited and not out-of-board positions.
for(int i=-2;i<3;i=i+4)
{
for(int j=-1;j<2;j=j+2)
{
list.add(next(square,i,j));
list.add(next(square,j,i));
}
}
}
bool knightTour(chess &board,position square, int count)
{
//cout<<count<<endl;
//Base Case if the problem is solved;
if(count>N2)
return true;
if(outsideChess(board,square))
return false;
//return false if the square is already visited
if(visited(board,square))
return false;
visitSquare(board,square,count);
Vector<position> nextSquareList; // <------------- HERE
calulateNextSquare(board,square,nextSquareList);
for(int i=0;i<nextSquareList.size();i++)
if(knightTour(board, nextSquareList[i], count+1))
return true;
unVisitSquare(board,square);
return false;
}
void printChess(chess &board)
{
for(int i=0;i<board.numRows();i++)
{
for(int j=0;j<board.numCols();j++)
cout<<setw(4)<<board[i][j];
cout<<endl;
}
}
int main()
{
chess board(N,N);
initializeBoard(board);
position start;
start.row = 0; start.col = 0;
if(knightTour(board,start,1))
printChess(board);
else
cout<<"Not Possible";
return 0;
}
But please note that you still have a exponential complexity, and optimizing your code wont change it.
You are passing a copy of the board to calculateNextSquare but it seems you don't need it in this method.
Also, you return a vector in this method but you should pass it by reference.