我最近在 Codility 上解决了 PrisonEscape 挑战。 Phosphorus
我得到 33/100 。我认为我的代码涵盖了所有的角落案例。不幸的是,它没有。
让我解释一下我的解决方案。
我已经在数组长度N + 1上创建了一个图表。我找到了所有的叶子并将它们作为可能的防护位置添加到队列中。然后我通过这些节点进行了探索。
我在下面添加了我的颂歌。我希望有人可以花费宝贵的时间来帮助我。感谢。
#include <queue>
struct Node{
vector<int> neighbours;
bool hasPrisoner;
bool guardPlaced;
bool isVisited;
unsigned int index;
Node(): hasPrisoner(false), guardPlaced(false),isVisited(false),index(0)
{
}
};
bool shouldBeGuarded(vector<Node>& intersections, int index, int callerIndex)
{
if(intersections[index].hasPrisoner)
{
return true;
}
else if(intersections[index].guardPlaced || intersections[index].isVisited)
{
return false;
}
bool result = false;
for(unsigned int i = 0 ; i < intersections[index].neighbours.size() && !result; ++i)
{
if(callerIndex == intersections[index].neighbours[i])
continue;
result = result || shouldBeGuarded(intersections, intersections[index].neighbours[i],index);
}
return result;
}
int solution(vector<int> &A, vector<int> &B, vector<int> &C)
{
// write your code in C++11
vector<Node> intersections;
intersections.resize(A.size()+1, Node());
for(unsigned int i=0 ; i < A.size() ; ++i)
{
intersections[A[i]].neighbours.push_back(B[i]);
intersections[B[i]].neighbours.push_back(A[i]);
if(i < C.size())
intersections[C[i]].hasPrisoner = true;
}
for(unsigned int i=0 ; i < intersections.size() ; ++i)
{
intersections[i].index = i;
}
queue<Node*> guardQueue;
for(unsigned int i=0 ; i < intersections.size() ; ++i)
{
if(intersections[i].neighbours.size() == 1)
{
if(intersections[i].hasPrisoner)
return -1;//Prisoners can't be on exits. If they are there, now way to keep them.
guardQueue.push(& intersections[i] );
}
}
Node* guardNode = NULL;
while(!guardQueue.empty())
{
guardNode = guardQueue.front();
guardQueue.pop();
if(guardNode->isVisited)
continue;
guardNode->isVisited = true;
if(guardNode->neighbours.size() == 1)
{
if(intersections[guardNode->neighbours[0]].hasPrisoner)
guardNode->guardPlaced = true;
else
{
guardQueue.push(&intersections[guardNode->neighbours[0]]);
}
}
else
{
vector<int> possibleNextMoves;
for(unsigned int i = 0 ; i < guardNode->neighbours.size(); ++i)
{
if(intersections[guardNode->neighbours[i]].hasPrisoner)
{
guardNode->guardPlaced = true;
break;
}
if(intersections[guardNode->neighbours[i]].isVisited || intersections[guardNode->neighbours[i]].guardPlaced)
continue;
possibleNextMoves.push_back(guardNode->neighbours[i]);
}
if(!guardNode->guardPlaced && !possibleNextMoves.empty())
{
if(possibleNextMoves.size() == 1)
{
guardQueue.push(&intersections[possibleNextMoves[0]]);
}
else
{
vector<int> needsGuardList;
for(unsigned int i = 0 ; i < possibleNextMoves.size(); ++i)
{
if(shouldBeGuarded(intersections,possibleNextMoves[i],guardNode->index))
needsGuardList.push_back(possibleNextMoves[i]);
}
if(needsGuardList.size() > 1)
{
guardNode->guardPlaced = true;
}
else if(needsGuardList.size() == 1)
guardQueue.push(&intersections[needsGuardList[0]]);
}
}
}
}
int counter = 0;
for(unsigned int i = 0 ; i < intersections.size(); ++i)
{
if(intersections[i].guardPlaced)
{
counter++;
}
}
return counter;
}
答案 0 :(得分:0)
“每个交叉路口附近都有一个单元格块”,所以不能没有一个未连接的交叉路口。尽管示例数组可以扩展为包含A [8] = 89 B [8] = 99,但先前的N / N + 1变为N + 1 / N + 1 + 2,这违反了“有N个走廊和N + 1交叉点“所以:没有。
更容易?如何在2小时内完成这项任务?单独的算法花了我4个小时。 Jules Pondart在45分钟内做到了,那是什么样的代码神,i.o.w。我是菜鸟吗?是否有java问题的答案?