I wrote down the code for knight tour problem, I couldn't figure out what is the actual issue with the solution, it's running fine upto n=6, but after that it is taking a long time to run. It's showing correct output but taking a really long time as I put n=7 or n=8 or higher. Here's my code:
#include<bits/stdc++.h>
using namespace std;
bool isSafe(vector<vector<int>> sol, int x, int y){
int n=sol.size();
return (x>=0 && x<n && y>=0 && y<n && sol[x][y]==-1);
}
bool findSolUtil(vector<vector<int>> &sol, vector<int> xMoves, vector<int> yMoves, int x, int y, int count){
int n=sol.size(), i, next_x, next_y;
if(count==n*n){
return true;
}
for(i=0; i<8; i++){
next_x = x+xMoves[i];
next_y = y+yMoves[i];
if(isSafe(sol, next_x, next_y)){
sol[next_x][next_y] = count;
if(findSolUtil(sol, xMoves, yMoves, next_x, next_y, count+1)){
return true;
}
sol[next_x][next_y] = -1;
}
}
return false;
}
void findSol(int n){
vector<vector<int>> sol(n, vector<int>(n, -1));
vector<int> xMoves = {2, 1, -1, -2, -2, -1, 1, 2};
vector<int> yMoves = {1, 2, 2, 1, -1, -2, -2, -1};
sol[0][0] = 0;
cout << findSolUtil(sol, xMoves, yMoves, 0, 0, 1);
}
int main(){
int n;
cout << "Size of the board is nXn, enter n : ";
cin >> n;
findSol(n);
return 0;
}
Related
I was trying to solve the rat in a mze problem (https://practice.geeksforgeeks.org/problems/rat-in-a-maze-problem/1). But I am getting SIGABRT at the commented line below. I was thinking for quite a lot of time why it is happening. Can you please help? Thank you.
#include <bits/stdc++.h>
using namespace std;
class Solution{
public:
vector<string> check(int i, int j, vector<vector<int>> &m,string str , vector<string> soln,int n)
{
if(i==n-1 && j==n-1){soln.push_back(str);return soln;}
m[i][j]=0;
if(i+1<=n-1 && m[i+1][j]!=0 ){str += "D"; check(i+1,j,m,str,soln,n);}
else if(j+1<=n-1 && m[i][j+1]!=0 )
{
str += "R";
check(i,j+1,m,str,soln,n);// This is causing the SIGABRT when str = "DDRDRR"
}
else if(i-1>=0 && m[i-1][j]!=0){str += "U"; check(i-1,j,m,str,soln,n);}
else if(j-1>=0 && m[i][j-1]!=0){str += "L"; check(i,j-1,m,str,soln,n);}
}
vector<string> findPath(vector<vector<int>> &m, int n) {
vector<string> paths;
vector<string> soln;
if(m[0][0]==0)return paths;
paths = check(0,0,m,"",soln,n);
return paths;
}
};
int main() {
int t;
t=1;
while (t--) {
int n;
n=4;
vector<vector<int>> m{{1, 0, 0, 0},{1, 1, 0, 1}, {1, 1, 0, 0},{0, 1, 1, 1}};
Solution obj;
vector<string> result = obj.findPath(m, n);
sort(result.begin(), result.end());
if (result.size() == 0)
cout << -1;
else
for (int i = 0; i < result.size(); i++) cout << result[i] << " ";
cout << endl;
}
return 0;
}
There's no default case if none of the conditions match, you're simply returning void which is not a vector.
To fix it, add return soln; to the end of the check function.
We have a set of objects indexed by integers and need to generate a list of pairs of possible combinations of these objects (of any length up to the number of objects) with a constraint. The constraint is that if one combination in a pair contains an object, then the other combination in that pair cannot also contain that object.
As an example, if we have only 3 objects { 0, 1, 2}, the list should look like
{ {0}, {1} }
{ {0}, {2} }
{ {1}, {2} }
{ {0,1}, {2} }
{ {0}, {1,2} }
{ {0,2}, {1} }
What is a computationally efficient way of generating this list for as many as 20 objects in C++?
In each pair, every object is either not used, or it's in the left set, or it's in the right set.
If you have N objects, you can easily iterate through the 3^N possibilities, skipping the ones that result in empty sets:
#include <iostream>
#include <vector>
using namespace std;
int main() {
unsigned N = 5; //number of objects
vector<unsigned> left, right;
for (unsigned index=0 ;; ++index) {
left.clear();
right.clear();
//treat the index as a number in base 3
//each digit determines the fate of one object
unsigned digits=index;
for (int obj=1; obj<=N; ++obj) {
unsigned pos=digits%3;
digits /= 3;
if (pos == 1)
left.push_back(obj);
else if (pos == 2)
right.push_back(obj);
}
if (digits) {
//done all possibilities
break;
}
if (left.empty() || right.empty()) {
// don't want empty left or right
continue;
}
//got one -- print it
cout << "{ {" <<left[0];
for (size_t i=1; i<left.size(); ++i)
cout << "," << left[i];
cout << "}, {" <<right[0];
for (size_t i=1; i<right.size(); ++i)
cout << "," << right[i];
cout << "} }" << endl;
}
return 0;
}
If unsigned is 32 bits, this will work for up to 20 objects. Note that it will print about 3.5 billion pairs in that case, though.
Try it here: https://ideone.com/KIeas7
Firstly we can decide which element will be in our pairs.
For example, if the number of element is 3, consider the binary representation from 0 to 2^3.
0=000
1=001
2=010
3=011
4=100
5=101
6=110
7=111
Now, we will make the pair from each number from 0 to 2^n by keeping the elements in which position the number has 1. Like 3=011, its first and second position have 1, so we will make a pair with first and second element.For 6=110,we will make the pair with second and third element.
So, we can decide which element we will take in our each pair through 2^n complexity, where n is the number of element.
Now we know which element will be in each pair.
For example, let for one pair we selected m elements. Now we need to divide them within each side. We can do it like the similar way by considering binary representation of all numbers from m elements.
If m=3,
0=000
1=001
2=010
3=011
4=100
5=101
6=110
7=111
So from each number from 0 to 2^m, we can make a pair. For making a pair from a number , we will keep the elements in first set which index has 0 in that number and will keep in the second set which index has 1 in that number.
C++ code:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long cnt=0;
int n;
cin>>n;
int object[n];
for(int i=0; i<n; i++)cin>>object[i];
for(int i=0; i<(1<<n); i++){
// From each i, we will decide which element will be in our set.
int c=0;
int nu=0;
int one_pair[n];
// Now we will calculate , how many elements will be in current pair.
for(int j=0; j<n; j++)if((i&(1<<j)))one_pair[c++]=object[j];
if(c>=2){
// So we have c element in each pair
for(int k=1; k<(1<<(c-1)); k++){
//Now we will divide each of the c element within two sides.
cout<<"{ {";
bool fl=0;
for(int divider=0;divider<c;divider++){
if((k&(1<<divider))){
if(fl)cout<<",";
fl=1;
cout<<one_pair[divider];
}
}
cout<<"}, ";
cout<<"{";
fl=0;
for(int divider=0;divider<c;divider++){
if((k&(1<<divider))==0){
if(fl)cout<<",";
fl=1;
cout<<one_pair[divider];
}
}
cout<<"} }"<<endl;
}
}
}
return 0;
}
Output:
3
0 1 2
{ {0}, {1} }
{ {0}, {2} }
{ {1}, {2} }
{ {0}, {1,2} }
{ {1}, {0,2} }
{ {0,1}, {2} }
Here's a recursive version that takes each combination in the powerset with more than one element and runs a "put in one bag or the other" routine. (It's pretty much my first time trying to code anything more than trivial in C++ so I imagine there may be room for improvement.)
Powerset:
{{0, 1, 2}, {0, 1}, {0, 2}, {0}, {1, 2}, {1}, {2}, {}}
{{0, 1}, {2}}
{{0, 2}, {1}}
{{0}, {1, 2}}
{{0}, {1}}
{{0}, {2}}
{{1}, {2}}
Code (also here):
#include <iostream>
#include <vector>
using namespace std;
void print(std::vector<int> const &input){
std::cout << '{';
for (int i = 0; i < input.size(); i++) {
std::cout << input.at(i);
if (i < input.size() - 1)
std::cout << ", ";
}
std::cout << '}';
}
void printMany(std::vector< std::vector<int> > const &input)
{
std::cout << '{';
for (int i = 0; i < input.size(); i++) {
print(input.at(i));
if (i < input.size() - 1)
std::cout << ", ";
}
std::cout << '}';
std::cout << '\n';
}
void printPairs(std::vector< std::vector<int> > const &input)
{
for (int i = 0; i < input.size(); i+=2) {
cout << '{';
print(input.at(i));
cout << ", ";
print(input.at(i + 1));
cout << "}\n";
}
}
std::vector< std::vector<int> > f(std::vector<int> const &A, int i, const std::vector<int> &left, const std::vector<int> &right) {
if (i == A.size() - 1 && right.empty())
return std::vector< std::vector<int> >{left, std::vector<int> {A[i]}};
if (i == A.size())
return std::vector< std::vector<int> > {left, right};
std::vector<int> _left{ left };
_left.emplace_back(A[i]);
std::vector< std::vector<int> > result = f(A, i + 1, _left, right);
std::vector<int> _right{ right };
_right.emplace_back(A[i]);
std::vector< std::vector<int> > result1 = f(A, i + 1, left, _right);
result.insert( result.end(), result1.begin(), result1.end() );
return result;
}
std::vector< std::vector<int> > powerset(std::vector<int> const &A, const vector<int>& prefix = vector<int>(), int i = 0) {
if (i == A.size())
return std::vector< std::vector<int> > {prefix};
std::vector<int> _prefix(prefix);
_prefix.emplace_back(A[i]);
std::vector< std::vector<int> > result = powerset(A, _prefix, i + 1);
std::vector< std::vector<int> > result1 = powerset(A, prefix, i + 1);
result.insert( result.end(), result1.begin(), result1.end() );
return result;
}
int main() {
std::vector<int> A{0, 1, 2};
std::vector< std::vector<int> > ps = powerset(A);
cout << "Powerset:\n";
printMany(ps);
cout << "\nResult:\n";
for (int i=0; i<ps.size(); i++){
if (ps.at(i).size() > 1){
std::vector<int> left{ps.at(i)[0]};
std::vector<int> right;
printPairs(f(ps.at(i), 1, left, right));
}
}
return 0;
}
I currently have the following data structure:
class DataStructure {
public:
DataStructure(int n) : m_data(n, 0) {
}
void update(int i, int j, int value) {
for (int k = i; k <= j; ++k) {
m_data[k] = max(m_data[k], value);
}
}
void reset(int i) {
m_data[i] = 0;
}
int query(int i) {
return m_data[i];
}
private:
vector<int> m_data;
};
So what it does is rather simple:
Initially there is a vector of n integers initialised to zero.
update(i, j, value) updates the elements in the range [i, j] to be the max of the given value and their respective current value. The given value is in the range of [0, n].
reset(i) resets the value at index i to 0.
query(i) returns the value at index i.
I need to perform n updates, n resets and n query operations. Currently this code takes O(n*n) time, due to the update operation being O(n) in general.
I am wondering if there are some smart ways to improve this to O(n*log n) time (or better) for n updates, n resets and n query operations, while maintaining O(n) space complexity?
Thanks for #qwertman for the explanation here is an algorithm that should work
#include <iostream>
#include <cstdio>
using namespace std;
#define max(a, b) (a>b?a:b)
int tree[100005], lazy[100005];
void init(int idx, int l, int r){
if(l>r)
return ;
if(l==r){
tree[idx] = 0;
lazy[idx] = -1;
}
else {
tree[idx] = 0;
lazy[idx] = -1;
int mid = (l+r)/2;
init(2*idx, l, mid);
init(2*idx+1, mid+1, r);
}
}
// l and r is for internal use the range a-b has to be updated
void update(int idx, int l, int r, int a, int b, int val, bool isReset){
if(l>r || b<l || a>r){
return;
}
// printf("idx=%d l=%d r=%d a=%d b=%d val=%d\n",idx,l,r,a,b,val);
if(lazy[idx] != -1){
tree[idx] = max(tree[idx], lazy[idx]);
lazy[2*idx] = max(lazy[2*idx], lazy[idx]);
lazy[2*idx+1] = max(lazy[2*idx+1], lazy[idx]);
lazy[idx] = -1;
}
if(l>=a && r<=b){
// printf("updating\n");
tree[idx] = max(tree[idx], val);
if(isReset){
tree[idx] = val;
}
lazy[2*idx] = max(lazy[2*idx], val);
lazy[2*idx+1] = max(lazy[2*idx+1], val);
lazy[idx] = -1;
}
else {
int mid = (l+r)/2;
update(2*idx, l, mid, a, b, val, isReset);
update(2*idx+1, mid+1, r, a, b, val, isReset);
tree[idx] = max(tree[2*idx], tree[2*idx+1]);
}
}
int query(int idx, int l, int r, int a){
if(l>r || a<l || a>r){
return -1;
}
// printf("idx=%d l=%d r=%d a=%d\n",idx,l,r,a);
if(lazy[idx] != -1){
tree[idx] = max(tree[idx], lazy[idx]);
lazy[2*idx] = max(lazy[2*idx], lazy[idx]);
lazy[2*idx+1] = max(lazy[2*idx+1], lazy[idx]);
lazy[idx] = -1;
}
if(l==a && r==a){
// printf("----l=%d r=%d a=%d tree=%d\n",l,r,a,tree[idx]);
return tree[idx];
}
else {
int mid = (l+r)/2;
int left = query(2*idx, l, mid, a);
int right = query(2*idx+1, mid+1, r, a);
return max(left, right);
}
}
int main() {
// initializing everything to 0
init(1, 1, 10);
// updating range 1-4 with value 7
update(1, 1, 10, 1, 4, 7, false);
// query for 3 should result in 7
cout << query(1, 1, 10, 3) << endl;
// updating 3-3 with value 9
update(1, 1, 10, 3, 3, 9, false);
// should give 9
cout << query(1, 1, 10, 3) << endl;
// isReset is set to true, so the function will do a hard reset
update(1, 1, 10, 3, 3, 0, true);
// should give 0
cout << query(1, 1, 10, 3) << endl;
return 0;
}
you can run this code at http://ideone.com/Mkp4dQ
some useful links for learning segment tree with lazy propagation hackerearth
Geeksforgeeks
I am trying to solve subset sum problem with recursive solution, but to make to make it a bit more efficient I am trying to put memoization in it. However the code without memoization gives correct solution but with memoization it doesn't work properly.
public int subsetSum(int num[], int idx, int expecedSum, int dp[]) {
if (expecedSum == 0) {
return 1;
}
else if (idx < 0 || expecedSum < 0) {
return 0;
}
else {
if (dp[expecedSum] == -1) {
int x = subsetSum(num, idx - 1, expecedSum, dp);
int y = subsetSum(num, idx - 1, expecedSum - num[idx], dp);
dp[expecedSum] = (x == 1 || y == 1) ? 1 : 0;
}
return dp[expecedSum];
}
}
public static void main(String args[]) {
Solution s = new Solution();
int num[] = new int[]{1, 2, 3, 4, 5, 6, 7};
int sum = 0;
int n = new Scanner(System.in).nextInt();
int dp[] = new int[n + 1];
for (int i = 0; i < dp.length; i++) {
dp[i] = -1;
}
dp[0] = 1;
s.subsetSum(num, num.length - 1, n, dp);
}
Can someone help me with why this is not working?
If I enter n = 14 then ideally dp[14] should contains 1 but it doesn't contain 1.
The sum is not sufficient to describe the state. The pair (sum, index) is. If you make dp an array of arrays of size (max_sum + 1) x num.length and apply memoization for a pair (idx, expectedSum) in the subsetSet method, it works.
It has been years but this may help someone today.
The idea is to take both the state - means once with including current element into the sum and once excluding current element into the sum. and then taking OR(||) for those values and store in the cache.
the code will look something like this -
#include <iostream>
#include <vector>
using namespace std;
bool sumExists(vector<int> & a, int cursum, int n, vector<vector<int>> &dp) {
if(n==0 && cursum != 0)
return 0;
if(cursum==0)
return 1;
if(dp[n][cursum] != -1) {
return dp[n][cursum];
}
int newsum = cursum - a[n-1];
bool returnval = false;
if(newsum>=0) {
dp[n][newsum] = sumExists(a, newsum, n-1, dp);
dp[n][cursum] = sumExists(a, cursum, n-1, dp);
returnval = dp[n][newsum] || dp[n][cursum];
} else {
dp[n][cursum] = sumExists(a, cursum, n-1, dp);
returnval = dp[n][cursum];
}
return returnval;
}
int main() {
// your code goes here
vector<int> a{2,0,7,8,10};
int n = a.size();
int sum = 11;
vector<vector<int>> dp(n+1, vector<int>(sum+1, -1));
for(int i=0;i<=n;++i) {
dp[i][0]=true;
}
for(int i=1;i<=sum;++i) {
dp[0][i]=false;
}
if(sumExists(a, sum, n, dp)) {
cout<<"YES"<<endl;
} else {
cout<<"NO"<<endl;
}
}
The binary index tree can be implemented in two dimension also. But unlike one dimensional implementation it requires an auxiliary array. What is the purpose of this auxilary array in this algorithm
The implementation is described in this article
using namespace std;
#define N 4 // N-->max_x and max_y
struct Query
{
int x1, y1; // x and y co-ordinates of bottom left
int x2, y2; // x and y co-ordinates of top right
};
void updateBIT(int BIT[][N+1], int x, int y, int val)
{
for (; x <= N; x += (x & -x))
{
for (; y <= N; y += (y & -y))
BIT[x][y] += val;
}
return;
}
// A function to get sum from (0, 0) to (x, y)
int getSum(int BIT[][N+1], int x, int y)
{
int sum = 0;
for(; x > 0; x -= x&-x)
{
// This loop sum through all the 1D BIT
// inside the array of 1D BIT = BIT[x]
for(; y > 0; y -= y&-y)
{
sum += BIT[x][y];
}
}
return sum;
}
void constructAux(int mat[][N], int aux[][N+1])
{
// Initialise Auxiliary array to 0
for (int i=0; i<=N; i++)
for (int j=0; j<=N; j++)
aux[i][j] = 0;
// Construct the Auxiliary Matrix
for (int j=1; j<=N; j++)
for (int i=1; i<=N; i++)
aux[i][j] = mat[N-j][i-1];
return;
}
// A function to construct a 2D BIT
void construct2DBIT(int mat[][N], int BIT[][N+1])
{
// Create an auxiliary matrix
int aux[N+1][N+1];
constructAux(mat, aux);
// Initialise the BIT to 0
for (int i=1; i<=N; i++)
for (int j=1; j<=N; j++)
BIT[i][j] = 0;
for (int j=1; j<=N; j++)
{
for (int i=1; i<=N; i++)
{
// Creating a 2D-BIT using update function
// everytime we/ encounter a value in the
// input 2D-array
int v1 = getSum(BIT, i, j);
int v2 = getSum(BIT, i, j-1);
int v3 = getSum(BIT, i-1, j-1);
int v4 = getSum(BIT, i-1, j);
// Assigning a value to a particular element
// of 2D BIT
updateBIT(BIT, i, j, aux[i][j]-(v1-v2-v4+v3));
}
}
return;
}
// A function to answer the queries
void answerQueries(Query q[], int m, int BIT[][N+1])
{
for (int i=0; i<m; i++)
{
int x1 = q[i].x1 + 1;
int y1 = q[i].y1 + 1;
int x2 = q[i].x2 + 1;
int y2 = q[i].y2 + 1;
int ans = getSum(BIT, x2, y2)-getSum(BIT, x2, y1-1)-
getSum(BIT, x1-1, y2)+getSum(BIT, x1-1, y1-1);
printf ("Query(%d, %d, %d, %d) = %d\n",
q[i].x1, q[i].y1, q[i].x2, q[i].y2, ans);
}
return;
}
// Driver program
int main()
{
int mat[N][N] = {{1, 2, 3, 4},
{5, 3, 8, 1},
{4, 6, 7, 5},
{2, 4, 8, 9}};
// Create a 2D Binary Indexed Tree
int BIT[N+1][N+1];
construct2DBIT(mat, BIT);
Query q[] = {{1, 1, 3, 2}, {2, 3, 3, 3}, {1, 1, 1, 1}};
int m = sizeof(q)/sizeof(q[0]);
answerQueries(q, m, BIT);
return(0);
}
What is the purpose of this auxilary array in this algorithm?
The auxilary array is needed in this algorithm because they have used the origin as the leftside bottom of the matrix, it wouldn't be required if they would have used leftside top as the origin point.