Here is an algo coding question:
There are stones in two dimension array, and given a known length rope, determine what's the maximum number of stones you can use the rope to surround? (the rope must be enclosed).
I think the question is to find the loop in undirected graph with maximal number of nodes and upper bound of length and BFS seems a good way, but seems still NP-hard.
EDIT:
Here is an example: 5 stones in a plane. I listed three surroundings: black, red and blue. The length of each surrounding is the sum of its strings.
The question is equivalent to select n of N points by order x1,...xn with its sum = d(x1,x2)+d(x2,x3)+...+d(xn-1,xn)+d(xn,x1) <= C. Here n>1. What's the maximal n?
Solution:
After some hints, I think it is nothing about the undirected graph. It is similar to the problem that selecting some elements from a given array equal to a target sum. But the difference is that the result depends on the selecting order, therefore we cannot select by the order from the given array. Here is my solution. But there are still a lot of duplicate searches, for example, if black loop is eligible, we have to search 4 times from each of its nodes.
double d(const vector<double> a, const vector<double> b)
{
return sqrt((a[0] - b[0])*(a[0] - b[0]) + (a[1] - b[1])*(a[1] - b[1]));
}
//recursive
//out: current legal elements; sum: the sum of out; ct: the maximal number up to now
//visited: record the elements in out has been visited to void duplicate visit
//res: help to check the result in debuge
void help(vector<vector<double>> array, double target, vector<vector<double>> &out, int &sum, int & ct, vector<vector<vector<double>>> &res, vector<bool> &visited)
{
for (int i = 0; i < array.size(); i++) //since it depends on the order of selection, we have to search from begining. visited helps us to skip the element already been in out.
{
if (visited[i]) continue;
else if (out.empty()) {out.push_back(array[i]); visited[i] = true;}
else
{
vector<double> last = out.back(), first = out.front();
if (sum + d(array[i], last) + d(array[i], first) <= target)
{
out.push_back(array[i]);
sum += d(array[i], last);
ct = max(ct, (int)out.size());
visited[i] = true;
help(array, target - d(array[i], last), out, sum, ct, res, visited);
out.pop_back();//when the loop is over at this level, we should return to the state of previous level
sum -= d(array[i], last);
visited[i] = false;
}
else
{
res.push_back(out);
return;
}
}
}
}
int Path(vector<vector<double>> array, double target) {
int sum = 0, ct = 0;
vector<vector<double>> out;
vector<vector<vector<double>>> res;
vector<bool> visited(array.size(), false);
help(array, target, out, sum, ct, res, visited);
return ct;
}