Replacing defined constant by an integer value in function with matrices - c++

I would like to modify the N-Queens backtracking algorithm by getting the size of the board (N) from the standard input instead of defining N as a constant.
However, I can't match the types at the functions. Should I define some kind of global maximum constant and then work with n?
Here's the code:
#include <iostream>
using namespace std;
bool safe(int N, char mat[][N], int v, int k)
{
int i, j;
for (i = 0; i < v; i++)
if (mat[i][k] == 'Q')
return false;
for (i = v, j = k; i >= 0 && j >= 0; i--, j--)
if (mat[i][j] == 'Q')
return false;
for (i = v, j = k; i >= 0 && j < N; i--, j++)
if (mat[i][j] == 'Q')
return false;
return true;
}
void backtrack(int N, char mat[][N], int v)
{
if (v == N)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
cout << mat[i][j] << " ";
cout << endl;
}
cout << endl;
return;
}
for (int i = 0; i < N; i++)
{
if (safe(N, mat, v, i))
{
mat[v][i] = 'Q';
backtrack(N, mat, v + 1);
mat[v][i] = '-';
}
}
}
int main()
{
int N;
cin >> N;
char mat[N][N];
memset(mat, '-', sizeof mat);
backtrack(N,mat, 0);
return 0;
}

char mat[N][N]; is a Variable Length Array (VLA) which is a non standard extension of some c++ compilers that you should avoid using. If you need run-time allocated memory, consider using a std::vector:
int N{};
std::cin >> N;
std::vector<std::vector<char>> mat(N, std::vector<char>(N, '-'));
will do what you want. You can then pass this to any function using:
void foo(const std::vector<std::vector<char>>& mat); // for read-only
void foo(std::vector<std::vector<char>>& mat); // for read-write
Note: this is potentially less effeccient depending on how memory is allocated. If you need your memory to line up all together, use a 1D vector and access function to get index for you.

Related

A number K and an Array of size N is given, check whether we can get the sum of any two elements of array equal to K

I tried to solve the problem but my code still contains some bugs. Why isn't it running?
Here is the link of the question website: https://www.hackerearth.com/practice/data-structures/hash-tables/basics-of-hash-tables/practice-problems/algorithm/pair-sums/?
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int n = 1e7 + 10;
int hsh[n];
int main()
{
int n, k;
cin >> n >> k;
int A[n];
for (int i = 0; i < n; i++)
{
cin >> A[i];
}
for (int i = 0; i < n; i++)
{
hsh[A[i]] = k - A[i];
}
int t = 0;
for (int i = 0; i < n; i++)
{
if (hsh[A[i]] == k - hsh[hsh[A[i]]])
{
cout << "YES";
t = 1;
break;
}
}
if (t == 0)
{
cout << "NO";
}
return 0;
}
The problem is that while hsh[A[i]] is always valid, hsh[hsh[A[i]] is not.
Consider the following input:
1 1
10000
This does the following:
A[0] = 10000;
...
hsh[10000] = 1 - 10000; // = -99999
...
if (hsh[10000] == 1 - hsh[-99999]) {...}
So your code is reading out of bounds of the array hsh[]. Make sure you check first if hsh[A[i]] >= 0.
Note that your code is more complicated than necessary; you can do a single loop over the input to check if there is a matching pair:
#include <iostream>
static constexpr int max_k = 2e6;
static bool seen[max_k + 1];
int main()
{
int n, k;
std::cin >> n >> k;
for (int i = 0; i < n; ++i)
{
int A;
std::cin >> A;
if (A <= k && seen[k - A]) {
std::cout << "YES\n";
return 0;
}
seen[A] = true;
}
std::cout << "NO\n";
}

Rotate a 2-D array by 90 degrees

How can I take the array size input from the user and pass it to the function. I tried #define inside the function, it doesn't work since the array definition needs the array bound at compile time. I tried global variable too, it says to define a integer constant which is not feasible in my case since I want to get the size from the user. How can I solve this issue?
#include <iostream>
using namespace std;
// reverse the transposed matrix as step 2
void reverseColumns(int arr[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N / 2; j++)
{
int temp = arr[i][j];
arr[i][j] = arr[i][N - j - 1];
arr[i][N - j - 1] = temp;
}
}
}
// take the transpose of matrix as step 1
void transposeMatrix(int arr[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = i; j < N; j++)
{
int temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
}
void rotateMatrix(int mat[N][N])
{
transposeMatrix(mat);
reverseColumns(mat);
}
// printing the final result
void displayMatrix(int mat[N][N])
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
cout << mat[i][j] << "\t";
cout << "\n";
}
cout << "\n";
}
int main()
{
int T, N;
cin >> T;
while (T > 0)
{
cin >> N;
int mat[N][N];
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> mat[i][j];
}
}
int res[N][N];
rotateMatrix(mat);
displayMatrix(mat);
}
return 0;
}
One way to make it work is get the input of rows and cols from user and make a one dimensional array dynamically.
for example:
Let ROWS and COLS be the values you got via cin.
Then the array can be declared as
int* arr = new int[ROWS * COLS];
Instead of writing arr[i][j] you have to write
arr[i * COLS + j]
Also you have to delete the array using
delete[] arr;
You are using C++ so you should take advantages of it. As kiner_shah commented the fast way to fix your code is just by use of std::vector<std::vector<int>>.
This is better solution but stil poor:
#include <iostream>
#include <vector>
using namespace std;
using Matrix = std::vector<std::vector<int>>;
Matrix makeSquereMatrix(size_t N)
{
return {N, std::vector<int>(N)};
}
// reverse the transposed matrix as step 2
void reverseColumns(Matrix& arr)
{
auto N = arr.size();
... // no changes here
}
// take the transpose of matrix as step 1
void transposeMatrix(Matrix& arr)
{
auto N = arr.size();
... // no changes here
}
void rotateMatrix(Matrix& mat)
{
transposeMatrix(mat);
reverseColumns(mat);
}
// printing the final result
void displayMatrix(const Matrix& mat)
{
for (auto& row : mat)
{
for (auto x : row)
cout << x << "\t";
cout << "\n";
}
cout << "\n";
}
void readMatrix(Matrix& m)
{
for (auto& row : m)
{
for (auto& x : row)
{
cin >> x;
}
}
}
int main()
{
int T, N;
cin >> T;
while (T > 0)
{
cin >> N;
auto mat = makeSquereMatrix(N);
readMatrix(mat);
rotateMatrix(mat);
displayMatrix(mat);
--T;
}
return 0;
}
Live demo
Better solution would be introducing a class containing std:::vector with methods performing required actions.
BTW some time ago I've made some matrix code for C. Here is live demo

HackerRank says ~no response on stdout~. C++

I wrote this solution for the absolute permutation problem on HackerRank. It works fine on dev-C++ but doesn't work on Hackerrank. I've found that the code produces output when I remove the abs_perm(). What's the problem here?
#include <iostream>
using namespace std;
int arr[100000];
int check(int n, int k)
{
if ( (2*k == n) || (k == 0) || (n - 4*k == 0) )
return 1;
else if (k < n/2)
return check(n - 4*k, k);
else
return 0;
}
void swap(int &a, int &b)
{
int c = b;
b = a;
a = c;
}
void ini(int n)
{
for (int i = 0; i < n; i++)
{
arr[i] = i+1;
}
}
void abs_perm(int n, int k)
{
for (int i = 0; i < k; i++)
{
swap(arr[i], arr[k+i]);
}
if (2*k == n)
return;
for (int i = n - 1; i > n - k - 1; i--)
{
swap(arr[i], arr[i-k]);
}
if (n - 4*k == 0)
return;
abs_perm(n - 4*k, k);
}
int main()
{
int T;
cin >> T;
int N[T], K[T];
for (int i = 0; i < T; i++)
{
cin >> N[i] >> K[i];
}
for (int i = 0; i < T; i++)
{
cout << N[i] << " " << K[i] << "\n";
}
for (int i = 0; i < T; i++)
{
if ( !check(N[i], K[i]) )
cout << "-1\n";
else
{
ini(N[i]);
abs_perm(N[i], K[i]);
for (int j = 0; j < N[i]; j++)
{
cout << arr[j] << " ";
}
cout << "\n";
}
}
return 0;
}
Array is a structure to use when you know at compile time the dimension of your structure. What you wrote at the begin in abs_perm() is not correct for standard compilers (in fact you don't know the dimension of your array). You can use a std::vector or a std::list which allocate memory dynamically or (bad solution) you can allocate an array with dimension that certainly contains all elements you will put inside.

Usage of multidimensional vectors

I was trying to use multidimensional vector and change the values of row and column.
#include<iostream>
#include<vector>
using namespace std;
void changerow(vector<vector<int> > A, int row, int M, int P){
for(int j = 0; j < M; j++){
(A[row - 1])[j] = ((A[row - 1])[j] + P) % 10;
}
}
void changecolumn(vector<vector<int> > A, int column, int N, int P){
for(int i = 0; i < N; i++){
(A[i])[column - 1] = ((A[i])[column - 1] + P) % 10;
}
}
int main(int argc, char* argv[])
{
int T, N, M;
cin >> T >> N >> M;
if((T >= 1 && T <= 10) && (M >= 1 && M <= 100) && (N >= 1 && N <= 100)){
// Logic of the program
vector<vector<int> > A(N, vector<int>(M));
for(int i = 0; i < N ; i++){
for(int j = 0; j < M; j++){
cin >> (A[i])[j];
}
}
changerow(A,2,M,3);
for(int i = 0; i < N ; i++){
for(int j = 0; j < M; j++){
cout << A[i][j];
}
}
}
return 0;
}
I don't know how would pass the address of the vector in order to change the element, since only the local copy of the vector gets passed. I am currently reading Thinking in C++ Volume 1 but its not elaborate. Kindly let me know a good source for learning the use of vectors in C++.
Currently, you are passing the vector by value, which means that the callee gets a copy of the vector.
If you wish the changes that the callee makes to be visible to the caller, you need to pass the vector by reference. This is done like so:
void changecolumn(vector<vector<int> >& A, int column, int N, int P){
^ THIS
For a discussion, see Pass by Reference / Value in C++

C++ for loop array assignment. Getting junk returned

I'm trying to generate LIMIT (lets say limit = 1000) prime numbers and store them to an array, but I get junk returned. Here's my code:
#include <iostream>
using namespace std;
void prime_num(int);
int main()
{
int primes[1000];
int n, p, t, LIMIT = 1000;
for(n=2; n <= LIMIT; n++)
{
t=0;
for(p=2; p <= n/2; p++)
{
if (n%p == 0)
{
t = 1;
break;
}
}
if(!t)
primes[p-2] = n;
}
for (int i = 0; i < LIMIT; i++)
cout << primes[i] <<" ";
return 0;
}
Define a variable outside the outer loop:
int count=0;
and then use it here:
primes[count++] = n;
then print as:
for (int i = 0; i < count; i++)
cout << primes[i] <<" ";
Explanation:
You're not generating 1000 prime numbers, rather you're generating all prime numbers less than or equal to 1000.
As #Jerry Coffin commented, your code should be like this:
Note : I'm not talking about correctness, rather the skeleton of the program; so you decide if is_prime() function is correct or not, optimized or not, etc.
bool is_prime(int n)
{
for(int p=2; p <= n/2; p++)
{
if (n%p == 0)
{
return false;
}
}
return true;
}
int main()
{
int primes[1000];
int n, p, t, LIMIT = 1000;
int count=0;
for(n=2; n <= LIMIT; n++)
{
if (is_prime(n) )
primes[count++] = n;
}
for (int i = 0; i < count; i++)
cout << primes[i] <<" ";
return 0;
}
Correctness and Optimization of is_prime():
Now you decide the correctness of is_prime(). Is it correctly written? Is it optimized? Do you really need to check for all integers in the range [2,n/2]?