There is an unlimited chessboard,
from the console we enter how many examples there will be and how many chess knights are on the board, and their starting positions (that is, where they are), and the points to which the knights must go in the least number of steps.
Here's what it should look like:
2 - number of examples
1 - the number of chess knights
5 5 - the starting point
5 6 - the final point
2 - the number of chess knights
0 0 - the starting point of the first knight
1 0 - the starting point of the second knight
0 1 - the final point of the first knight
1 1 - the final point of the second knight
Answer:
3 - the answer for the first example
4 - the answer for the second example
The problem is that it doesn't work out that way, because with the first data set everything is fine, but with the second it does not work out the correct answer.
If we take the points separately, then the answer in the second data set is 6 (3 for the first knight and 3 for the second knight).
I have guesses how to solve it, but it does not work.
The conjecture is that when the second knight begins to move, it passes the same points that the first knight passed (the second example) and you probably need to write down the conditions if the first knight was already at these positions, then the second cannot pass them again.
The second conjecture is that you need to write down the conditions for the board and make it unlimited, and make the knight walk the negative values of the chessboard.
Here is a sample photo (below):
Please help, I will be very grateful !!!
#include <iostream>
#include <set>
#include <queue>
#include <climits>
using namespace std;
#define N 8
// Below arrays details all 8 possible movements
// for a knight
int row[] = { 2, 2, -2, -2, 1, 1, -1, -1 };
int col[] = { -1, 1, 1, -1, 2, -2, 2, -2 };
// Check if (x, y) is valid chess board coordinates
// Note that a knight cannot go out of the chessboard
bool valid(int x, int y)
{
if (x < 0 || y < 0 || x >= N || y >= N)
return false;
return true;
}
// queue node used in BFS
struct Node
{
// (x, y) represents chess board coordinates
// dist represent its minimum distance from the source
int x, y, dist;
// Node constructor
Node(int x, int y, int dist = 0): x(x), y(y), dist(dist) {}
// As we are using struct as a key in a std::set,
// we need to overload < operator
// Alternatively we can use std::pair<int, int> as a key
// to store coordinates of the matrix in the set
bool operator<(const Node& o) const
{
return x < o.x || (x == o.x && y < o.y);
}
};
// Find minimum number of steps taken by the knight
// from source to reach destination using BFS
int BFS(Node src, Node dest)
{
// set to check if matrix cell is visited before or not
set<Node> visited;
// create a queue and enqueue first node
queue<Node> q;
q.push(src);
// run till queue is not empty
while (!q.empty())
{
// pop front node from queue and process it
Node node = q.front();
q.pop();
int x = node.x;
int y = node.y;
int dist = node.dist;
// if destination is reached, return distance
if (x == dest.x && y == dest.y)
return dist;
// Skip if location is visited before
if (!visited.count(node))
{
// mark current node as visited
visited.insert(node);
// check for all 8 possible movements for a knight
// and enqueue each valid movement into the queue
for (int i = 0; i < 8; ++i)
{
// Get the new valid position of Knight from current
// position on chessboard and enqueue it in the
// queue with +1 distance
int x1 = x + row[i];
int y1 = y + col[i];
if (valid(x1, y1))
q.push({x1, y1, dist + 1});
}
}
}
// return INFINITY if path is not possible
return INT_MAX;
}
// main function
int main()
{
// source coordinates
Node src = {0, 7};
// destination coordinates
Node dest = {7, 0};
cout << "Minimum number of steps required is " << BFS(src, dest);
return 0;
}
According to the data you give, the two knights should move like this:
first knight: (0,0) -> (0,1)
second knight: (1,0) -> (1,1)
However, in your diagram, you imply that the knights should move like this (ignoring the wrong x-Axis that is missing the 1):
first knight: (0,0) -> (1,1)
second knight: (0,1) -> (1,0)
Your diagram moves each knight to the final position of the other knight, which is not correct. Your code gives 6, the correct solution to move each knight to its own final position as indicated by the data you give.
This is an answer assuming the ending positions are not linked to the knights (any knight can end up in any ending position). This is an algorithmic question independent of programming languages, so I won't show any code.
The simplest, but least efficient way would be to assume each knight has a single required final position. You assign all permutations of the final positions to the knights by index and for each permutation, calculate the result. Finally, you return the minimal result. In your example, one result would be 6 (original mapping), the other one would be 4 (swapped final positions, the only other permutation), so you'd get 4. The problem with this approach is that for n knights, you'll have n! permutations to consider.
The greedy approach would be for each knight to move until it hits one of the final spots, then for the other to hop to the other. This would work for your example but goes wrong for this one:
Knights: (5,4), (2,1); Final positions: (3,3), (9,6)
First knight would move
(5,4) -> (3,3)
and is done (1 step), second knight will then have to move
(2,1) -> (4,2) -> (5,4) -> (7,5) -> (9,6)
This needs 4 steps, making a total of 5. However, the optimal solution is:
(5,4) -> (7,5) -> (9,6)
(2,1) -> (3,3)
Which are 3 steps. So we see, a naive greedy algorithm does not necessarily yield a correct result.
However, we can do better with a greedy approach: First, calculate the distances between each knight/final position pair, and store them (using your original algorithm).
Our previous example would look like this:
(5,4) <- first knight
(3,3) = 1 <- distance to first final position
(9,6) = 2 <- distance to second final position
(2,1) <- second knight
(3,3) = 1
(9,6) = 4
Once you have calculated those, the algorithm will subsequently assign an ending position to the knights. It will work like this:
Loop over all knights that do not yet have an ending position. For each knight, mark the nearest final position and calculate the penalty on the other knights. The penalty is the maximum of additional moves for all other knights that have not yet been assigned. For example, selecting (3,3) for the knight at (5,4) would have a penalty of 3, since the other knight will now need to move 3 additional steps (as we marked its nearest final position). However, selecting (3,3) for the knight at (2,1) has a penalty of 1 because the other knight only needs to move one additional step.
After you calculated all penalties, assign the knight with the smallest penalty its nearest final position. Loop until all knights have been assigned a final position.
This algorithm is correct for both your original example and my example, however I don't know whether it's always correct. You'd need to prove that.
I want to solve a problem that gives the (integral) coordinates of n points (n<=10^5)
and asks q queries (q<=10^4). In each query it gives the (integral) coordinates of two other points and we need to answer how many of the n points are located within the rectangle created by those two points.
(edit) Also the coordinates are huge (x,y <= 10^9) (/edit)
I created a quad tree and then used this function to get the answer, however i get time limit exceeded (time limit = 2s). Is this approach too slow or have I done something wrong?
int sum(int left, int right, int down, int up, int i=1, int begx=0, int endx=1e9, int begy=0, int endy=1e9)
{
if (!i || left>right || down>up) return 0;
if (left==begx && right==endx && down==begy && up==endy) return num[i];
int midx = (begx+endx)/2, midy = (begy+endy)/2;
return sum(left,min(midx,right),down,min(midy,up),child[i][0],begx,midx,begy,midy)
+ sum(left,min(midx,right),max(midy+1,down),up,child[i][1],begx,midx,midy+1,endy)
+ sum(max(midx+1,left),right,down,min(midy,up),child[i][2],midx+1,endx,begy,midy)
+ sum(max(midx+1,left),right,max(midy+1,down),up,child[i][3],midx+1,endx,midy+1,endy);
}
If I comment this function out (and don't answer the queries, just add the points to the quad tree) I get an execution time of about 0.2 secs.
Array num stores the sum of a node and child stores the index of the four children of each node. Node 0 is dummy. The partitioning of a rectangle in children looks like this:
___
|1 3|
|0 2|
---
I'm trying to write my own A* pathfinding algorithm and have a problem; when seeking the shortest cost path the following error arises:
Where the green filled node is the start node, the red filled node is the goal node and the pink filled nodes are the actual path that the algorithm has taken.
This is of course not the shortest path and I'm certain the problem lies with my heuristic function (manhattan distance):
int Map::manhattanDistance(Node evaluatedNode, Node goalNode)
{
int x = evaluatedNode.xCoord - goalNode.xCoord;
int y = evaluatedNode.yCoord - goalNode.yCoord;
if(x + y < 0)
return (x + y) * -1;
else
return x + y;
}
It seems to me that manhattan distance formula is not ideal here and my question is therefore: what other distance measuring algorithm would work for me here?
EDIT: for sake of clarity, each nodes width is determined by number of nodes in row / screen width = 640 and each nodes height is determined by number of nodes in column / screen height = 480.
A negative cost would imply that a route is free, or more than that it discounts previous moves. It looks like you have tried to account for this by multiplying by -1 of the aggregate, however the damage has already been done. That is why the solution has used diagonals, (1 - 1) * -1 is still zero and thus is considered to be free.
I would replace the if statement with the following, which uses the magnitude of each component by applying abs against it separately:
return Math.abs(x) + Math.abs(y);
I'm deciding how to store data and how to draw a tree graph. Assuming I want a minimum space M between two elements, I was thinking I could traverse the entire tree structure from the top to the bottom in breath-first search.
If there's just one element below the current one, it will be drawn with the same X coordinate as his father. If there are two elements, they will be drawn one at -M/2 and the other at +M/2 with respect to their father X coordinate. And so on..
The problem is: what if an element like C (see diagram below) has a great number of children?? I should restructure the entire tree since I should move the element D to the left and make space for all the E-F children of C. Moving D to the left will get the tree crooked and I will need to move B too. Moving B to the left would alter the tree's symmetry so I'll need to move C too and so on..
How can I draw a perfectly symmetric tree whose elements may have a large number of children?
Do it the other way up: compute each node's horizontal position from those of its children after they've been computed. Something like this (WARNING: completely untested code; may consist entirely of bugs):
void Node::place_self(coord_t x0, coord_t y0) {
this->y0 = y0; this->y1 = y0+height;
if (!left && !right) {
// This is a leaf. Put its top left corner at (x0,y0).
this->x0 = x0; this->y0 = y0;
this->subtree_x1 = x0+width;
}
else if (!left || !right) {
// Only one child. Put this immediately above it.
Node * child = left ? left : right;
child->place_self(x0,y0+height+gap);
coord_t xc = child->x0 + child->width/2;
this->x0 = xc-width/2;
this->subtree_x1 = max(this->x0+width, child->subtree_x1);
}
else {
// Two children. Put this above their midline.
left->place_self(x0, y0+height+gap);
right->place_self(left->subtree_x1+gap, y0+height+gap);
coord_t xc = (x0 + right->subtree_x1)/2;
this->x0 = xc-width/2;
this->subtree_x1 = max(this->x0+width, right->subtree_x1);
}
}
i want to find the height of a tree in sml.The tree is not a regular one it could have any number of nodes at a level.Futher the datatypes that it holds is also abstract.could someone help me out with it.
As other have said, then please post what ever definition of a tree you have, and what code you have come up with so far.
I assume that you have already defined your own tree structure or you have had it defined in the assignment, anyways this ought not to be your problem so here is simple binary tree structure using a Node and an empty Leaf as constructors.
datatype 'a tree = Leaf
| Node of ('a tree) * 'a * ('a tree)
val t1 = Node (Leaf, 1, Leaf)
val t2 = Node (t1, 2, Leaf)
val t3 = Node (Leaf, 3, Leaf)
val t = Node (t2, 4, t3)
Ascii representation of t
4
/ \
/ \
2 3
/ \ / \
1 * * *
/ \
* *
Where * represents the leafs
Given this representation of a binary tree, you could create a function that calculates the height in a bottom up maner. You mainly have to consider two cases:
What are the height of a tree only containing a leaf?
What are the height of a Node that has a left sub-tree of height l and a right sub-tree of height r?
If we look at t2 from the above example
2
/ \
1 *
/ \
* *
Then obviously the right sub-tree has height x (depends on how you define the height of leafs) and the left sub-tree has height 0. The Height of t2 must then be 1 (0+1).
Considering t then it has a left sub-tree of height 1 (as we have just found out) and the right sub-tree has height 0. Thus t must have height 2 (1+1)
I have seen many quick implementation of a height function that counts the root node, but this is not correct.
Here
height is defined as the number of links from the root to the deepest leaf