Modification of code for printing cycles in the graph - c++

#include<bits/stdc++.h>
using namespace std;
void addEdge(vector<vector<int > >&adj,int u,int v)
{
adj[u].push_back(v);
}
bool DFS(vector<vector<int > >adj,int x,vector<bool>&visited,vector<bool>&recStack,stack<int>&s)
{
if(recStack[x])
{
return true;
}
if(visited[x])
{
return false; // the node is already visited and we didn't a cycle with this node
}
visited[x]=true;
recStack[x]=true;
s.push(x);
for(int i=0;i<adj[x].size();i++)
{
if(DFS(adj,adj[x][i],visited,recStack,s))
{
return true;
}
}
recStack[x]=false;
s.pop();
return false;
}
bool graphHasCycle(vector<vector<int > >adj)
{
vector<bool>visited(adj.size(),false);
vector<bool>recStack(adj.size(),false);
stack<int>s;
for(int i=0;i<adj.size();i++)
{
if(DFS(adj,i,visited,recStack,s))
{
while(!s.empty())
{
cout<<s.top()<<" ";
s.pop();
}
return true;
}
}
return false;
}
int main()
{
/*int n=3,e=3;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,2,0);*/
/*int n=3,e=3;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,0,2);*/
/*int n=4,e=4;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,2,3);
addEdge(adj,3,1);*/
/*int n=5,e=6;
vector<vector<int > >adj(n,vector<int>());
addEdge(adj,0,1);
addEdge(adj,1,2);
addEdge(adj,0,2);
addEdge(adj,0,3);
addEdge(adj,3,4);
addEdge(adj,4,0);*/
cout<<"Adjacency list:\n";
for(int i=0;i<adj.size();i++)
{
for(int j=0;j<adj[i].size();j++)
{
cout<<adj[i][j]<<" ";
}
cout<<endl;
}
cout<<"Cycles:\n";
if(graphHasCycle(adj))
{
cout<<"Graph has cycle";
}
else
{
cout<<"No cycle";
}
return 0;
}
Code source:'Detect cycle in directed graph' from GeeksForGeeks.
Im trying to modify this code to also print the cycles using this code,but it doesnt seem to work on all cases.
for example in the graph with edges 0->1,1->2,2->3,3->1,it would print the cycle as 3 2 1 0 but the actual cycle is 3 2 1.It also fails when two cycles originate from the same vertex.
Please help me correct the code to print the cycles correctly.
Link to the code in online ide:
https://ide.geeksforgeeks.org/ujCcvL77ii

I think before each DFS call, you need to re-initialize recStack to false as below:
for(int i=0;i<adj.size();i++)
{
vector<bool>recStack(adj.size(),false); //for each call we need an empty recStack
stack<int>s; //initialize a new stack too.
if(DFS(adj,i,visited,recStack,s))

Related

Finding next palindrome of a number, getting SIGABRT error

Hi ,I am trying to solve the question PALIN on SPOJ where the idea is to find the next immediate palindrome of a number. I tested my code on the IDE with all possible test cases I found and the program is working fine but I can't figure out why I am getting SIGABRT error when I submit the solution.Please I request someone help me figure out the problem in the code For yor reference I am providing the link of the question:- https://www.spoj.com/problems/PALIN/
#include<iostream>
#include<stdio.h>
#include<vector>
#include<string>
using namespace std;
bool all_nines(string s)
{
for(int i=0;i<s.length();i++)
{
if(s[i]!='9')
return false;
}
return true;
}
int reverse(int a)
{
int rev=0;
while(a)
{
rev=(rev*10)+(a%10);
a/=10;
}
return rev;
}
void convert_and_compare(string &s,int low,int high)
{
int low_num,high_num;
string low_str="",high_str="";
for(int i=0,j=high;i<=low,j<s.size();i++,j++)
{
low_str+=s[i];
high_str+=s[j];
}
low_num=stoi(low_str);
high_num=stoi(high_str);
if(reverse(low_num)<=high_num)
{
low_num++;
low_str=to_string(low_num);
high_str="";
for(int i=low_str.length()-1;i>=0;i--)
high_str+=low_str[i];
}
else
{
high_str="";
for(int i=low_str.length()-1;i>=0;i--)
high_str+=low_str[i];
}
s="";
s+=low_str+high_str;
}
void convert_and_compare(string &s,int low,int high,int mid)
{
int low_num,high_num,mid_num;
string low_str="",high_str="";
char mid_str;
for(int i=0,j=high;i<=low,j<s.size();i++,j++)
{
low_str+=s[i];
high_str+=s[j];
}
low_num=stoi(low_str);
high_num=stoi(high_str);
mid_num=(s[mid]-'0');
if(reverse(low_num)>high_num)
{
low_str=to_string(low_num);
high_str="";
for(int i=low_str.length()-1;i>=0;i--)
high_str+=low_str[i];
mid_str=mid_num+'0';
}
else if(reverse(low_num)<=high_num && mid_num!=9)
{
mid_num++;
high_str="";
for(int i=low_str.length()-1;i>=0;i--)
high_str+=low_str[i];
mid_str=mid_num+'0';
}
else if(reverse(low_num)<=high_num && mid_num==9)
{
mid_num=0;
low_num++;
low_str=to_string(low_num);
high_str="";
for(int i=low_str.length()-1;i>=0;i--)
high_str+=low_str[i];
mid_str=mid_num+'0';
}
s="";
s=low_str+mid_str+high_str;
}
string find_next_palin(string s)
{
if(all_nines(s))
{
s[0]='1';
for(int i=1;i<s.length();i++)
s[i]='0';
s+='1';
return s;
}
else
{
if(s.length()%2==0)
{
int low,high;
low=s.length()/2-1;
high=s.length()/2;
convert_and_compare(s,low,high);
return s;
}
else
{
int low,high,mid;
mid=s.length()/2;
low=mid-1;
high=mid+1;
convert_and_compare(s,low,high,mid);
return s;
}
}
}
int main()
{
int t;
scanf("%d",&t);
vector <string> v(t);
for(int i=0;i<t;i++)
{
cin>>v[i];
}
for(int i=0;i<t;i++)
{
if(v[i].length()==1)
{
if(v[i]=="9")
{ printf("11");
printf("\n");
}
else
{
printf("%d",(v[i][0]-'0')+1);
printf("\n");
}
}
else
{
string temp;
temp=find_next_palin(v[i]);
for(int j=0;j<temp.length();j++)
cout<<temp[j];
printf("\n");
}
}
return 0;
}

I have written a C++ program to solve sudoku puzzle ,it is showing "Exception has occurred. EXC_BAD_ACCESS"

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

Getting Error in this program: Checking if two array equal?

While compiling the program an error is popping up which I'm not able to figure out what it is: "No matching function call to _distance_fw(int&,int&)".
Here in this problem I'm trying to check if two arrays are equal in terms of the values they contain.
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
unordered_map<int,int> bucket;
unordered_map<int,int>::const_iterator it;
int main()
{
int T,N,val,counter;
int def=1;
bool bug;
scanf("%d",&T);
{
for(int i=0;i<T;i++)
{
scanf("%d",&N); //N is the size of array
counter=N;
bucket.erase(bucket.begin(),bucket.end());
for(int j=0;j<2;j++)
//scanning the first array
{
while(counter>0)
{
if(j==0)
{
scanf("%d",&val);
it=bucket.find(val);
if(it==bucket.end())
{
bucket.insert(val,def);
}
else
{
bucket[val]++;
}
}
else
{
scanf("%d",&val);
it=bucket.find(val);
if(it!=bucket.end())
{
bucket[val]--;
}
else
{
bug=true;
}
}
counter--;
}
if(bug==true)
{
cout<<"0"<<endl;
}
else
{
for(it=bucket.begin();it!=bucket.end();it++)
{
if(it->second!=0)
{
cout<<"0"<<endl;bug=true;break;
}
}
if(bug==false)
{
cout<<"1"<<endl;
}
}
}
}
}
}
You simply need to change
bucket.insert(val,def)
Into:
bucket.insert({val,def})
std::unordered_map::insert needs a std::unordered_map::value_type which in this case is std::pair<const int int>.
And please format your code better.

Wrong Answer http://www.spoj.com/problems/WORDS1/

I have written the following code for the above problem.
I have checked if Graph is connected by choosing the start node and doing DFS from it. And checking the conditions for Euler path and tour, in code that would be count= 2 or 0. It's working on all given test cases.But getting wrong answer on submission
#include<iostream>
#include<cmath>
#include<list>
#include<string>
#include<stack>
using namespace std;
class Graph
{
int V;
list<int> *adj;
int *in;
public:
Graph(int v)
{
this->V=v;
this->adj=new list<int>[V];
this->in=new int[V];
for(int i=0;i<V;i++)
{
in[i]=0;
}
}
void addEdge(int src,int des)
{
adj[src].push_back(des);
in[des]=in[des]+1;
}
void DFSUtil(bool visited[],int v)
{
stack<int> s;
s.push(v);
visited[v]=true; //mark v as visited;
while (!s.empty())
{
int top=s.top();
s.pop();
list<int> :: iterator it;
for(it=adj[top].begin();it!=adj[top].end();it++)
{
if(!visited[*it])
{
visited[*it]=true;
s.push(*it);
}
}
}
}
/*void DFSUtil(bool visited[],int v)
{
visited[v]=true;
list<int> :: iterator it;
for(it=adj[v].begin();it!=adj[v].end();it++)
{
if(!visited[*it])
{
DFSUtil(visited,*it);
}
}
}*/
// Graph reverseGraph()
// {
// Graph g(V);
// for(int i=0;i<V;i++)
// {
// list<int> :: iterator it;
// for(it=adj[i].begin();it!=adj[i].end();it++)
// {
// g.addEdge(*it,i);
// }
// }
// return g;
// }
bool isConnected()
{
//bool visited[V];
bool* visited=new bool[V];
for(int i=0;i<V;i++)
visited[i]=false;
int i=0;
int flag=0;
int n;
for(i=0;i<V;i++)
{
if(adj[i].size()>0)
{
n=i;
flag=1;
}
if(((int)adj[i].size()-in[i])==1 && in[i]==0) //selecting the start vertex i.e vertex with no incoming edges
{
n=i;
break;
}
}
if(i==V&&flag==0)
return 0;
DFSUtil(visited,n); //dfs to check if every node is reachable fro start vertex
for(int i=0;i<V;i++)
{
if(visited[i]==false && adj[i].size()>0)
return 0;
}
// Graph gr=reverseGraph();
// for(int i=0;i<V;i++)
// visited[i]=false;
// gr.DFSUtil(visited,n);
// for(int i=0;i<V;i++)
// {
// if(visited[i]==false && adj[i].size()>0)
// return 0;
// }
return 1;
}
bool isEuler()
{
int count=0;
int magnitude;
for(int i=0;i<V;i++) //check conditions on in and out edges, out edges=adj[].size
{
magnitude=in[i]-(int)adj[i].size();
if(magnitude<0)
magnitude=magnitude*-1;
if((magnitude)==1)
{
count=count+1;
}
else if(in[i]!=adj[i].size())
{
return 0;
}
}
if(count==1 || count>2)
return 0;
if(isConnected()==0) //check if graph is connected
return 0;
return 1;
}
};
int main()
{
int t;
//scanf("%d",&t);
cin>>t;
while(t--)
{
int n;
//scanf("%d",&n);
cin>>n;
string str;
if(n==1) //only one string entered
{
cin>>str;
cout<<"Ordering is possible.\n";
continue;
}
Graph g(26);
int src,des;
for(int i=0;i<n;i++)
{
cin>>str;
src=str[0]-'a';
des=str[str.length()-1]-'a';
g.addEdge(src,des);
}
if(g.isEuler())
{
cout<<"Ordering is possible.\n";
}
else
{
cout<<"The door cannot be opened.\n";
}
}
}
In your function isConnected, you attempt to find the start vertex with no incoming edges by breaking out of the for loop upon a certain condition. If this condition is not encountered, the loop variable i will contain the value 26, rather than an expected index in the range 0..25. When the value 26 is passed to the DFSUtil function it will caused an out of bounds array access. I get a crash on the line visited[v] = true;
A condition that will cause this to arise, is the test case from the linked site with the repeated word:
2
ok
ok
Your check to find the start vertex does not handle this case well.

Knight Tour C++

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.