i was trying to solve a breadth first search problem on spoj.the problem statement is as follows:
An equidivision of an n × n square array of cells is a partition of the n^2 cells in the array in exactly n sets, each one with n contiguous cells. Two cells are contiguous when they have a common side.
the problem link is:http://www.spoj.com/problems/EQDIV/
my code:http://ideone.com/OjluJG
#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
#include<queue>
using namespace std;
#define pii pair< int, int>
int n, m, grid[105][105];
char inp[101 * 101];
bool inRange(int i, int j)
{
m = n;
return (i >= 0 && i < n && j >= 0 && j < m);
}
int main()
{
int i, j, comp;
scanf("%d", &n);
while (n != 0)
{
if (n == 1)
{
printf("good\n");
scanf("%d", &n);
continue;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
grid[i][j] = 0;
}
}
int a, b, start1[n], start2[n], print = 0, c, d;
queue< pii > Q;
pii p;
getchar();
for (i = 1; i <= n - 1; i++)
{
gets(inp);
stringstream ss(inp);
for (j = 1; j <= n; j++)
{
ss >> a >> b;
if (j == 1)
{
start1[i - 1] = a;
start2[i - 1] = b;
//printf("%d %d\n",start1[i-1],start2[i-1]);
}
grid[a - 1][b - 1] = i;
}
}
for (int x = 0; x < n; x++)
{
int count = 1;
if (x == n - 1)
{
comp = 0;
p.first = c;
p.second = d;
Q.push(p);
}
else
{
comp = x + 1;
p.first = start1[x] - 1;
p.second = start2[x] - 1;
Q.push(p);
}
while (!Q.empty())
{
p = Q.front();
i = p.first;
j = p.second;
Q.pop();
grid[i][j] = -1;
if (x != n - 1)
{
if (inRange(i + 1, j) && grid[i + 1][j] == 0)
{
c = i + 1;
d = j;
}
if (inRange(i - 1, j) && grid[i - 1][j] == 0)
{
c = i - 1;
d = j;
}
if (inRange(i, j + 1) && grid[i][j + 1] == 0)
{
c = i;
d = j + 1;
}
if (inRange(i, j - 1) && grid[i][j - 1] == x + 1)
{
c = i;
d = j - 1;
}
}
if (inRange(i + 1, j) && grid[i + 1][j] == comp)
{
p.first = i + 1;
p.second = j;
Q.push(p);
count += 1;
}
if (inRange(i - 1, j) && grid[i - 1][j] == comp)
{
p.first = i - 1;
p.second = j;
Q.push(p);
count += 1;
}
if (inRange(i, j + 1) && grid[i][j + 1] == comp)
{
p.first = i;
p.second = j + 1;
Q.push(p);
count += 1;
}
if (inRange(i, j - 1) && grid[i][j - 1] == comp)
{
p.first = i;
p.second = j - 1;
Q.push(p);
count += 1;
}
}
if (count != n)
{
print = 1;
printf("wrong\n");
break;
}
}
if (print == 0)
printf("good\n");
//printf("%d %d\n",c,d);
scanf("%d", &n);
}
}
i am getting wrong answer ,don't know why?
can someone provide the testcase for which it is wrong?
Related
I am trying to understand the implementation of the Rabin-Karp algorithm. d is the number of characters in the input alphabet, but if I replace 0 or any other value instead of 20, it won't affect anything. Why is this happening like this ?
// Rabin-Karp algorithm in C++
#include <string.h>
#include <iostream>
using namespace std;
#define d 20
void rabinKarp(char pattern[], char text[], int q) {
int m = strlen(pattern);
int n = strlen(text);
int i, j;
int p = 0;
int t = 0;
int h = 1;
for (i = 0; i < m - 1; i++)
h = (h * d) % q;
// Calculate hash value for pattern and text
for (i = 0; i < m; i++) {
p = (d * p + pattern[i]) % q;
t = (d * t + text[i]) % q;
}
// Find the match
for (i = 0; i <= n - m; i++) {
if (p == t) {
for (j = 0; j < m; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == m)
cout << "Pattern is found at position: " << i + 1 << endl;
}
if (i < n - m) {
t = (d * (t - text[i] * h) + text[i + m]) % q;
if (t < 0)
t = (t + q);
}
}
}
int main() {
// char text[] = "ABCCDXAEFGX";
char text[] = "QWERTYUIOPASDFGHJKLXQWERTYUIOPASDFGHJKLX";
char pattern[] = "KLXQW";
int q = 13;
rabinKarp(pattern, text, q);
}
I believe the short answer is that the lower d is the more hash collisions you will have, but you go about verifying the match anyway so it does not affect anything.
A bit more verbose:
First let me modify your code to be have more expressive variables:
// Rabin-Karp algorithm in C++
#include <string.h>
#include <iostream>
using namespace std;
#define HASH_BASE 0
void rabinKarp(char pattern[], char text[], int inputBase) {
int patternLen = strlen(pattern);
int textLen = strlen(text);
int i, j; //predefined iterators
int patternHash = 0;
int textHash = 0;
int patternLenOut = 1;
for (i = 0; i < patternLen - 1; i++)
patternLenOut = (patternLenOut * HASH_BASE) % inputBase; // hash of pattern len
// Calculate hash value for pattern and text
for (i = 0; i < patternLen; i++) {
patternHash = (HASH_BASE * patternHash + pattern[i]) % inputBase;
textHash = (HASH_BASE * textHash + text[i]) % inputBase;
}
// Find the match
for (i = 0; i <= textLen - patternLen; i++) {
if (patternHash == textHash) {
for (j = 0; j < patternLen; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == patternLen)
cout << "Pattern is found at position: " << i + 1 << endl;
}
if (i < textLen - patternLen) {
textHash = (HASH_BASE * (textHash - text[i] * patternLenOut) + text[i + patternLen]) % inputBase;
if (textHash < 0)
textHash = (textHash + inputBase);
}
}
}
int main() {
// char text[] = "ABCCDXAEFGX";
char text[] = "QWEEERTYUIOPASDFGHJKLXQWERTYUIOPASDFGHJKLX";
char pattern[] = "EE";
int q = 13;
rabinKarp(pattern, text, q);
}
The easiest way to attack it is to set HASH_BASE (previously d) to zero and see where we can simplify. The rabinKarp function can then be reduced to:
void rabinKarp(char pattern[], char text[], int inputBase) {
int patternLen = strlen(pattern);
int textLen = strlen(text);
int i, j; //predefined iterators
int patternHash = 0;
int textHash = 0;
int patternLenOut = 0;
// Calculate hash value for pattern and text
for (i = 0; i < patternLen; i++) {
patternHash = (pattern[i]) % inputBase;
textHash = (text[i]) % inputBase;
}
// Find the match
for (i = 0; i <= textLen - patternLen; i++) {
if (patternHash == textHash) {
for (j = 0; j < patternLen; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == patternLen)
cout << "Pattern is found at position: " << i + 1 << endl;
}
if (i < textLen - patternLen) {
textHash = (text[i + patternLen]) % inputBase;
if (textHash < 0)
textHash = (textHash + inputBase);
}
}
}
now you'll notice that all the hashes becomes is the sum of the letters mod some number (in your case 13, in my case 2). This is a bad hash, meaning many things will sum to the same number. However, in this portion of the code:
if (patternHash == textHash) {
for (j = 0; j < patternLen; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == patternLen)
cout << "Pattern is found at position: " << i + 1 << endl;
}
you explicitly check the match, letter by letter, if the hashes match. The worse your hash function is, the more often you will have false positives (which will mean a longer runtime for your function). There are more details, but I believe that directly answers your question. What might be interesting is to record false positives and see how the false positive rate increases as d and q decrease.
I've read many posts but I can't figure out where is my error so I go with it.
My program throws the segfault at the cout<<endl. When I erase it, the program doesn't even print anything. It just prints the segfault. Aparently the program never reach to sort the vector.
#include <iostream>
#include <vector>
using namesapce std
void inserctionSort(std::vector<double> &v, int i, int j)
{
double temp;
for(i; i < v.size(); i++)
{
temp = v[i];
j = i - 1;
while((v[j] > temp) && (j >= 0))
{
v[j+1] = v[j];
j--;
}
v[j+1] = temp;
}
}
void merge_(std::vector<double> &v, int i, int k, int j)
{
std::vector<double> w(v.size());
int n = j - i + 1;
int p = i;
int q = k + 1;
for(int l = 0; l < n; l++)
{
if(p <= k && (q > j || v[p] <= v[q]))
{
w[l] = v[p];
p++;
}else
{
w[l] = v[q];
q++;
}
}
for(int l = 0; l < n; l++)
v[i - 1 + l] = w[l];
}
void mergeSort(std::vector<double> &v, int i, int j)
{
int n = j - i + 1, n0 = 3;
int k;
if(n <= n0)
{
inserctionSort(v,i,j);
}else
{
k = i - 1 + n / 2;
mergeSort(v, i, k);
mergeSort(v, k + 1, j);
merge_(v, i, k, j);
}
}
int main()
{
vector<double> v1 = {3.2,4.1,55.42,2.24,5.424,667.32,35.54};
cout<<"Vector desordenado: ";
for(int i = 0; i < v1.size(); i++)
cout<<v1[i]<<", ";
cout<<"hola";
cout<<endl;
cout<<"hola";
mergeSort(v1, 0, v1.size()-1); //--> Core generado
//quickSort(v1, 0, v1.size()-1);
cout<<"Vector ordenado: ";
for(int i = 0; i < v1.size(); i++)
cout<<v1[i]<<", ";
return 0;
}
You have problems in your code with vector indices assuming value -1 inside a couple of loops.
I have corrected these mistakes below, a working version of your code:
#include <iostream>
#include <vector>
using namespace std;
void inserctionSort(vector<double> &v, int i, int j)
{
int v_size = v.size();
double temp;
for (; i < v_size; i++) {
temp = v[i];
j = i - 1;
while ( (j >= 0) && (v[j] > temp) ) { // swapped conditions, as when j=-1, v[j]>temp is undefined
v[j+1] = v[j];
j--;
}
v[j+1] = temp;
}
}
void merge_(vector<double> &v, int i, int k, int j)
{
vector<double> w( v.size() );
int n = j - i + 1;
int p = i;
int q = k + 1;
for (int l = 0; l < n; l++) {
if ( p <= k && (q > j || v[p] <= v[q]) ) {
w[l] = v[p];
p++;
} else {
w[l] = v[q];
q++;
}
}
for(int l = 0; l < n; l++)
v[i + l] = w[l]; // deleted -1 from v[i - 1 + l], as it leads to v[-1] for i,l = 0
}
void mergeSort(vector<double> &v, int i, int j)
{
int n = j - i + 1, n0 = 3; // n = v.size()
int k;
if (n <= n0) {
inserctionSort(v,i,j);
} else {
k = i - 1 + n / 2;
mergeSort(v, i, k);
mergeSort(v, k + 1, j);
merge_(v, i, k, j);
}
}
int main()
{
vector<double> v1 = {3.2,4.1,55.42,2.24,5.424,667.32,35.54};
cout<<"Vector desordenado: ";
for (unsigned i = 0; i < v1.size(); i++)
cout<<v1[i]<<", ";
cout << "hola";
cout << endl;
cout << "hola";
mergeSort(v1, 0, v1.size()-1); //--> Core generado
//quickSort(v1, 0, v1.size()-1);
cout<<"Vector ordenado: ";
for (unsigned i = 0; i < v1.size(); i++)
cout << v1[i] << ", ";
return 0;
}
So the numbers pattern going like this :
Input : 2
Output :
0 0 0 1 0 0 0
0 0 2 0 12 0 0
0 3 0 0 0 11 0
4 0 0 0 0 0 10
0 5 0 0 0 9 0
0 0 6 0 8 0 0
0 0 0 7 0 0 0
I have solved it using usual method, but when I tried with array, the output is really messed up. Any suggestion how to make this number pattern with array?
This is my code that creates this number pattern :
int input, n, mid, i, j;
cin >> input;
n = (2*input)+3;
mid = (n+1)/2;
for(i = 1; i <= n; i++) {
for (j = 1; j <= mid; j++) {
if (i <= mid && j == mid-i+1) cout << i << " ";
else if (i > mid && j == mid-n+i) cout << i << " ";
else cout << "0 ";
}
for (j = mid+1; j <= n; j++) {
if (i >= mid && j == n+mid-i) cout << (2*n-i) << " ";
else if (i < mid && j == mid+i-1) cout << (2*n-i) << " ";
else cout << "0 ";
}
cout << endl;
}
Thanks in advance.
I think this code(working) might help you.
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main() {
int input, n, mid, i, j;
cin >> input;
n = (2*input)+3;
mid = (n+1)/2;
int arr[n][n];
memset(arr, 0, sizeof(arr));
for(i = 1; i <= n; i++) {
for (j = 1; j <= mid; j++) {
if (i <= mid && j == mid-i+1) arr[i - 1][j - 1] = i;
else if (i > mid && j == mid-n+i) arr[i - 1][j - 1] = i;
}
for (j = mid+1; j <= n; j++) {
if (i >= mid && j == n+mid-i) arr[i - 1][j - 1] = 2 * n - i;
else if (i < mid && j == mid+i-1) arr[i - 1][j - 1] = 2 * n - i;
}
}
}
Supplementing baymaxx, if you desire dynamic memory allocation:
#include <iostream>
#include <stdio.h>
#include <string.h>
int input, n, mid, i, j;
cin >> input;
n = (2*input)+3;
mid = (n+1)/2;
// create array of the specified size.
int** arr = (int**) malloc (n * sizeof(int**));
for (int p = 0; p < n; ++p) {
arr[p] = (int*) malloc(n * sizeof(int));
for (int q = 0; q < n; ++q) {
arr[p][q] = 0;
}
}
// fill array (algorithm attr. baymaxx)
for(i = 1; i <= n; i++) {
for (j = 1; j <= mid; j++) {
if (i <= mid && j == mid-i+1) {
arr[i - 1][j - 1] = i;
}
else if (i > mid && j == mid-n+i) {
arr[i - 1][j - 1] = i;
}
}
for (j = mid+1; j <= n; j++) {
if (i >= mid && j == n+mid-i) {
arr[i - 1][j - 1] = 2 * n - i;
}
else if (i < mid && j == mid+i-1) {
arr[i - 1][j - 1] = 2 * n - i;
}
}
}
// print array
for (int p = 0; p < n; ++p) {
for (int q = 0; q < n; ++q) {
int x = arr[p][q];
std::cout << x << " ";
}
std::cout << endl;
}
// delete array
for (int i = 1; i < n; ++i) {
free(arr[i]);
}
free(arr);
So I have a program in C++ that calls a function three times, I'm making this project using Code::Blocks and when I run the release version of the .exe it tells me that the program has stopped working and that I have to close the program. I tried calling the function just once and it works, no matter which call I leave. So it looks like it crashes only when it's called twice, regardless of which variables I pass. Any idea of why this happens?
Here's the function I call:
int interval(int h, int i, std::vector< std::vector<int> >& Array, int arr[], int interv)
{
int k = i + 1;
int P[20];
int number;
bool a;
int b;
int N;
int maxres;
int result[90];
for (h = 0; h < 20; h++)
{
for (N = 1; N <= 90; N += 1)
{
result[N] = 0;
for (i = 1; i <= (k - interv); i++)
{
number = Array[i - 1][h] - N;
if (number <= 0)
number += 90;
for (b = 0; b < 20; b++)
{
a = false;
if ((number == Array[i][b]) || ( (interv == 1) && (number == Array[i + 1][b]) ) || ( (interv == 2) && (number == Array[i + 2][b]) ) )
{
a = true;
result[N]++;
break;
}
}
if (!a)
break;
}
if (N == 1)
maxres = N;
else
{
if (result[N] >= result[maxres])
maxres = N;
}
}
P[h] = maxres;
}
for (h = 0; h < 20; h++)
{
arr[h] = Array[0][h] + P[h];
if ( arr[h] > 90 )
arr[h] -= 90;
}
return 0;
}
And here are the calls:
int c[20];
int e[20];
int d[20];
interval(h, i, Array, c, 0);
interval(h, i, Array, e, 1);
interval(h, i, Array, d, 2);
One problem is out-of-bounds accesses to result:
int result[90];
for (h = 0; h < 20; h++)
{
for (N = 1; N <= 90; N += 1) <--- Here!
{
result[N] = 0;
The allowed values for N are 0 to 89 (like in for (N = 0; N != 90; ++N))
There might be a similar problem here
for (i = 1; i <= (k - interv); i++)
but I can't tell for sure.
I am trying to solve this SPOJ problem. The question asks to find the shortest path for each black(1) pixel.
Since it is a unweighted graph I used BFS.
for input:
3 3
010
000
000
it's giving:
323
434
343
instead of:
101
212
323
This is my code
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
typedef pair < int, int >ii;
int R, C, i, j;
queue < ii > myQueue;
int visit[100][100];
int dist[100][100];
void bfs(ii s)
{
int i, j;
int count = 0;
ii node;
memset(visit, 0, sizeof(visit));
memset(dist, 0, sizeof(dist));
myQueue.push(s);
dist[node.first][node.second] = 0;
while (!myQueue.empty()) {
node = myQueue.front();
myQueue.pop();
if (visit[node.first][node.second])
continue;
visit[node.first][node.second] = 1;
//cout << node.first << " " << node.second << "\n";
i = node.first;
j = node.second;
if (j - 1 < R && j - 1 >= 0) {
myQueue.push(make_pair(i, j - 1));
if(dist[i][j - 1] == 0)
dist[i][j - 1] = dist[i][j] + 1;
}
if (j + 1 < R && j + 1 >= 0) {
myQueue.push(make_pair(i, j + 1));
if(dist[i][j+1] == 0)
dist[i][j + 1] = dist[i][j] + 1;
}
if (i - 1 < C && i - 1 >= 0) {
myQueue.push(make_pair(i - 1, j));
if(dist[i-1][j] == 0)
dist[i - 1][j] = dist[i][j] + 1;
}
if (i + 1 < C && i + 1 >= 0) {
myQueue.push(make_pair(i + 1, j));
if(dist[i+1][j] == 0)
dist[i + 1][j] = dist[i][j] + 1;
}
}
}
int main()
{
char input[100][100];
scanf("%d %d", &R, &C);
for (i = 0; i < R; i++)
scanf("%s", &input[i]);
int GRID[R][C];
for (i = 0; i < R; i++)
for (j = 0; j < C; j++)
GRID[i][j] = input[i][j] - '0';
for (i = 0; i < R; i++)
for (j = 0; j < C; j++) {
if (GRID[i][j] == 1)
bfs(make_pair(i, j));
}
for (i = 0; i < R; i++) {
for (j = 0; j < C; j++) {
printf("%d", dist[i][j]);
}
printf("\n");
}
}
ideone
Try this:
if (j - 1 < R && j - 1 >= 0) {
myQueue.push(make_pair(i, j - 1));
if(dist[i][j - 1] == 0)
dist[i][j - 1] = dist[i][j] + 1;
}
do this for all dist[][].
You have doubled result may be because you run your BFS twice between paired vertices.
But I'm not sure.