I am doing this problem http://community.topcoder.com/stat?c=problem_statement&pm=2915&rd=5853, but my program gives wrong output, I tried more ways and it does not work properly. I do not get it, because other people do it like me and they are fine. Can you please check if I have properly implemented the BFS? Thanks in advance.
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
#define P push
#define PP pop();
#define T front();
int mo[][2] = { {-2, -1}, {-2, 1}, {2, -1}, {2, 1}, {-1, -2}, {1, -2}, {-1, 2}, {1, 2} };
int m[8][8];
int BFS(int sy, int sx, int fy, int fx)
{
queue<int> s;
m[sy][sx] = 1;
s.P(sy);
s.P(sx);
s.P(0);
while(!s.empty())
{
int d = s.T s.PP
int x = s.T s.PP
int y = s.T s.PP
for(int i=0;i < 8;i++)
{
int yy = y + mo[i][0];
int xx = x + mo[i][1];
if(yy < 0 || yy > 7 || xx < 0 || xx > 7) continue;
if(m[yy][xx] != -1) continue;
if(yy == fy && xx == fx) return d + 1;
m[yy][xx] = 0;
s.P(yy);
s.P(xx);
s.P(d+1);
}
}
return -1;
}
class CaptureThemAll {
public:
int fastKnight(string knight, string rook, string queen) {
vector<int> p{knight[0] - 'a', knight[1] - '1', rook[0] - 'a', rook[1] - '1', queen[0] - 'a', queen[1] - '1'};
memset(m, -1, sizeof(m));
int a = BFS(p[1], p[0], p[3], p[2]);
memset(m, -1, sizeof(m));
int b = BFS(p[1], p[0], p[5], p[4]);
memset(m, -1, sizeof(m));
int c = BFS(p[3], p[2], p[5], p[4]);
return min(a,b) + c;
}
};
I think the problem might be that you push y,x,d so your queue will be
Front y Middle x End d
But when you pop the front element you place it (y) into a variable called d.
It may work better if you change:
int d = s.T s.PP
int x = s.T s.PP
int y = s.T s.PP
to
int y = s.T s.PP
int x = s.T s.PP
int d = s.T s.PP
Related
I am running into buffer overflow with the following solution to https://leetcode.com/problems/shortest-path-in-a-grid-with-obstacles-elimination/
class Solution {
public:
struct pt {
int x;
int y;
int k;
int s;
pt(int x, int y, int k, int s): s(s), x(x), y(y), k(k) {}
};
int shortestPath(vector<vector<int>>& grid, int k) {
int height = grid.size(), width = grid[0].size();
std::vector<std::pair<int, int>> dirs {{1,0}, {0, 1}, {-1, 0}, {0, -1}};
std::vector<std::vector<int>> maxKs(height, std::vector<int>(width, -1));
std::queue<pt> q;
q.push(pt(0, 0, k, 0));
while ( !q.empty() ) {
auto f = q.front();
q.pop();
if (f.x == width-1 && f.y == height-1) return f.s;
if (maxKs[f.x][f.y] >= f.k || f.k < 0) continue;
maxKs[f.x][f.y] = f.k;
for (auto dir : dirs) {
int x = f.x + dir.first;
int y = f.y + dir.second;
if (x < 0 || y < 0 || x == width || y == height) continue;
int curK = f.k - (grid[x][y] == 1);
if (curK < 0) continue;
q.push(pt(x,y,curK,f.s + 1));
}
}
return -1;
}
};
Wondering if anyone has ideas as to what is happening here?
You declared the size as
int height = grid.size(), width = grid[0].size();
but you are using width as the number of elements of grid and height as the number of grid[x].
maxKs[f.x][f.y] should be maxKs[f.y][f.x] and grid[x][y] should be grid[y][x].
I'm testing some programms for my lectures. I'm creating classes and use a paramterlist to initalize a field but the second variable doesn't change.
#include <iostream>
using namespace std;
class Punkt {
int x;
int y;
public:
Punkt(int a = 0, int b = 0)
{
x = a;
y = b;
}
void printXY()
{
cout << "x= " << x << " y= " << y << endl;
}
};
int main() {
Punkt pFeld[] = { (1, 1), (2, 2), (3, 3) };
for (int i = 0; i < 3; i++)
pFeld[i].printXY();
cin.get();
};
No error messages. Expected result was that x and y change, while actual result is that only x changes and y stays 0.
This
(1, 1)
is an expression with the comma operator.
In fact this initialization
Punkt pFeld[] = { (1, 1), (2, 2), (3, 3) };
is equivalent to
Punkt pFeld[] = { 1, 2, 3 };
So the constructor with the second default argument equal to 0 is called three times.
Use instead
{ 1, 1 }
Here is your updated code
#include <iostream>
using namespace std;
class Punkt {
int x;
int y;
public:
Punkt(int a = 0, int b = 0)
{
x = a;
y = b;
}
void printXY()
{
cout << "x= " << x << " y= " << y << endl;
}
};
int main() {
Punkt pFeld[] = { {1, 1}, {2, 2}, {3, 3} };
for (int i = 0; i < 3; i++)
pFeld[i].printXY();
cin.get();
}
Its output is
x= 1 y= 1
x= 2 y= 2
x= 3 y= 3
Pay attention to that the semicolon after the function main is redundant.
Passing (1, 1) to the constructor of Punkt, the comma operator will return the 2nd operand as the result (the 1st operand is discarded), so you're only passing one int with value 1 to the constructor. That's why y is always initialized as 0.
What you want should be
Punkt pFeld[] = { {1, 1}, {2, 2}, {3, 3} }; // list initialization since C++11
or
Punkt pFeld[] = { Punkt(1, 1), Punkt(2, 2), Punkt(3, 3) };
I have a C++ code in Tensorflow as shown below which involves the multiplication of matrices using placeholders:
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <iostream>
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"
int main(int argc, char const *argv[]){
using namespace tensorflow;
using namespace tensorflow::ops;
Scope root = Scope::NewRootScope();
auto alpha = Const(root, 2.0, {1, 1});
auto beta = Const(root, 3.0, {1, 1});
auto A = Placeholder(root, DT_FLOAT);
auto B = Placeholder(root, DT_FLOAT);
auto C = Placeholder(root, DT_FLOAT);
auto temp1 = MatMul(root, A, B);
auto temp2 = Mul(root, alpha, temp1);
auto temp3 = Mul(root, beta, C);
auto D = Add(root.WithOpName("D"), temp1, temp3);
std::vector<Tensor> outputs;
ClientSession session(root);
int num_size = 2;
for(int step = 1; step < num_size; step++){
/*Allocating arrays*/
int array_size = pow(10, step);
float **a, **b, **c;
a = (float **)malloc(sizeof(float)*array_size);
b = (float **)malloc(sizeof(float)*array_size);
c = (float **)malloc(sizeof(float)*array_size);
for(int i = 0; i < array_size; i++){
a[i] = (float *)malloc(sizeof(float)*array_size);
b[i] = (float *)malloc(sizeof(float)*array_size);
c[i] = (float *)malloc(sizeof(float)*array_size);
}
srand((unsigned)time(0));
for(int i = 0; i < array_size; i++){
for(int j = 0; j < array_size; j++){
a[i][j] = (rand()%100)+1;
b[i][j] = (rand()%200)+1;
c[i][j] = (rand()%300)+1;
}
}
for(int num = 0; num < 10; num++){
Status s = session.Run({{A, a}, {B, b}, {C, c}}, {D}, &outputs);
if(s.ok())
c = outputs[0];
else
printf("Error\n");
}
}
return 0;
}
However the format of sending values to placeholders in C++ is shown in this link. The feedtype used in C++ is given here.
I'm confused as to how I can modify my 2D arrays to the feeddict format so as to supply in 'session.Run()'.
Thank you.
Edit 1
A minimal representation of the question is as follows-
Consider the following snippet of code:
Scope root = Scope::NewRootScope();
auto a = Placeholder(root, DT_INT32);
// [3 3; 3 3]
auto b = Const(root, 3, {2, 2});
auto c = Add(root, a, b);
ClientSession session(root);
std::vector<Tensor> outputs;
// Feed a <- [1 2; 3 4]
int feed_a[2][2] = {{1, 2}, {3, 4}};
session.Run({ {a, feed_a} }, {c}, &outputs);
// The working code is - session.Run({ {a, { {1, 2}, {3, 4} } } }, {c}, &outputs);
// outputs[0] == [4 5; 6 7]
How can I make this code work in the case shown where the 'feed_a' array is received from a separate function and it needs to be used to set the value of placeholder 'a'.
You need to create a c-array and place the data there instead of using a jagged array.
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"
int main() {
using namespace tensorflow;
using namespace tensorflow::ops;
Scope root = Scope::NewRootScope();
// [3 3; 3 3]
auto b = Const(root, {{3.f, 3.f}, {3.f, 3.f}});
ClientSession session(root);
std::vector<Tensor> outputs;
// just print b
TF_CHECK_OK(session.Run({}, {b}, &outputs));
LOG(INFO) << "b = ";
LOG(INFO) << outputs[0].matrix<float>();
// just print c = a + b
float *a_data = new float[4];
for (int i = 0; i < 4; ++i)
a_data[i] = 1.f;
auto a_shape = TensorShape({2, 2});
auto a_init = Input::Initializer(*a_data, a_shape);
auto a_plhdr = Placeholder(root, DT_FLOAT);
auto c = Add(root, a_plhdr, b);
TF_CHECK_OK(session.Run({{a_plhdr, a_init}}, {c}, &outputs));
LOG(INFO) << "a + b";
LOG(INFO) << outputs[0].matrix<float>();
return 0;
}
gives me
2018-02-14 22:45:47.469766: I tensorflow/cc/example/example.cc:20] b =
2018-02-14 22:45:47.469800: I tensorflow/cc/example/example.cc:21] 3 3
3 3
2018-02-14 22:45:47.473519: I tensorflow/cc/example/example.cc:36] a + b
2018-02-14 22:45:47.473543: I tensorflow/cc/example/example.cc:37] 4 4
4 4
Note, for some reason
int32 *a_data = new int32[4];
for (int i = 0; i < 4; ++i)
a_data[i] = 1;
auto a_shape = TensorShape({2, 2});
auto a_init = Input::Initializer(*a_data, a_shape);
auto a_plhdr = Placeholder(root, DT_INT32);
produces a failure (no output):
Check failed: dtype() == expected_dtype (1 vs. 3)
which could not be solved by a
auto a_casted = Cast(root, a_plhdr, DT_FLOAT)
auto c = Add(root, a_casted, b);
i am doing a standard problem to calculate min moves to reach target by a knight but i also want to keep track of path but its showing error.it dispalys
prog.cpp: In function
'int minStepToReachTarget(int*, int*, int)':
prog.cpp:76:42: error: no match for 'operator[]' (operand types are
'std::vector<cell>' and 'cell')
{q.push(cell(x, y, t.dis + 1));parent[cell(x, y, t.dis + 1)]=t;}
I have commented down the line 76 in my code.
struct cell {
int x, y;
int dis;
cell() {}
cell(int x, int y, int dis): x(x), y(y), dis(dis) {}
};
//cell parent[10000];
typedef cell c;
vector<c> parent(10000);
bool isInside(int x, int y, int N) {
if (x >= 1 && x <= N && y >= 1 && y <= N)
return true;
return false;
}
int minStepToReachTarget(int knightPos[], int targetPos[], int N) {
// x and y direction, where a knight can move
int dx[] = {-2, -1, 1, 2, -2, -1, 1, 2};
int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1};
// queue for storing states of knight in board
queue<cell> q;
// push starting position of knight with 0 distance
q.push(cell(knightPos[0], knightPos[1], 0));
cell t;
int x, y;
bool visit[N + 1][N + 1];
// make all cell unvisited
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
visit[i][j] = false;
visit[knightPos[0]][knightPos[1]] = true;
// parent[cell(knightPos[0], knightPos[1], 0)]=t;
// loop untill we have one element in queue
while (!q.empty()) {
t = q.front();
//parent[t]=t;
q.pop();
visit[t.x][t.y] = true;
// if current cell is equal to target cell,
// return its distance
if (t.x == targetPos[0] && t.y == targetPos[1])
return t.dis;
// loop for all reahable states
for (int i = 0; i < 8; i++) {
x = t.x + dx[i];
y = t.y + dy[i];
// If rechable state is not yet visited and
// inside board, push that state into queue
if (isInside(x, y, N) && !visit[x][y]) {
q.push(cell(x, y, t.dis + 1));
//76 ERROR: parent[cell(x, y, t.dis + 1)]=t;}
}
}
}
int main() {
// size of square board
int N = 6;
int knightPos[] = {4, 5};
int targetPos[] = {1, 1};
int m= minStepToReachTarget(knightPos, targetPos, N);
cout<<m<<endl;
return 0;
}
#Code
int dx[8] = {-1,-2, 1 ,2 ,-1, -2, 1, 2};
int dy[8] = {-2,-1, -2,-1, 2, 1, 2, 1};
q.push(ppi(pi(kx, ky), 0));
while(!q.empty()){
pi cur = q.front().first; int d = q.front().second; q.pop();
int x = cur.first;
int y = cur.second;
// printf("%d %d %d\n", x,y, visited[x][y]);
if(visited[x][y]) continue;
visited[x][y] = true;
if (x == tx && y == ty){
printf("%d", d);
return 0;
}
for(int i = 0; i<8; i++){
int nx = x+dx[i];
int ny = y+dy[i];
if(nx <= 0 || nx > n || ny <= 0 || ny > n) continue;
q.push(ppi(pi(nx, ny), d+1));
}
}
printf("-1");
Explanation
Here, this is the bfs which I implemented. I am storing the grid as a boolean value, I can keep track of which squares I have traveled too. If I am unable to reach the square, I output -1. I would also recommend not using function calls unless really necessary, as this is a simple BFS question.
Extension
Just in case you want to find out more, I took the following chunk from my code for a harder problem, where there exists a grid with forbidden squares where the knight cannot travel. In that case, forbidden squares are initially marked as 'true' instead of 'false' to signify that is traveled so I will not go on it.
I hope my above solution helps.
I'm working on a numerical simulation program, for simplicity I recreated the code into expanding circles on a domain bounded on each side. I want to track each circle's radius. If I have this code:
int const N = 10;
int D[N+2][N+2]; //domain bounded on each side
int const nCircle = 4;
int center[nCircle][2] = {{1, 1}, {N, N}, {N, 1}, {1, N}};
void eval(); //function to expand circles
int main() {
for (int n=0;n<5;n++) {
eval();
for (int y=1;y<=N;y++) {
for (int x=1;x<=N;x++) {
printf("%d ", D[x][y]);
}
printf("\n");
}
printf("\n");
}
}
for visualization and simplicity purpose,
add these into global definition
double radius[nCircle] = {2, 2, 2, 2}; //actually unknown, i want to track this
void eval() {
double a;
for (int z=0;z<nCircle;z++) {
for (int y=1;y<=N;y++) {
for (int x=1;x<=N;x++) {
a = pow(x-center[z][0], 2) + pow(y-center[z][1], 2);
if (a <= pow(radius[z], 2))
D[x][y] = 1;
}
}
radius[z] += ((double) rand() / (RAND_MAX));
}
}
How do I do that?
edit:
note that circles might overlap each other, array D only store the union of circle area without information of the intersections.
Cannot declare a global array with a variable size (VLA). Use a compile time constant.
// int const N = 10;
#define N 10
int D[N+2][N+2];
// int const nCircle = 4;
#define nCircle 4
int center[nCircle][2] = {{1, 1}, {N, N}, {N, 1}, {1, N}};
double radius[nCircle] = {2, 2, 2, 2};
Alternatively use C99, and declare D[] and center[] inside main(). Code could use another method to use data in eval() like eval(N, D, nCircle, center, radius)
int main() {
int const N = 10;
int D[N+2][N+2] = {0}; // Initialize D
int const nCircle = 4;
int center[nCircle][2] = {{1, 1}, {N, N}, {N, 1}, {1, N}};
double radius[nCircle] = {2, 2, 2, 2};