我是这个网站的新手,所以我可能无法正确提出我的问题,对此我感到抱歉,但是我已经在PSET 3 Tideman上苦苦挣扎了一段时间。目前我正在使用lock_pairs,但我不知道该怎么办。感谢您的帮助! 这些是我提示check50的提示:
:) lock_pairs locks all pairs when no cycles
:( lock_pairs skips final pair if it creates cycle
lock_pairs did not correctly lock all non-cyclical pairs
:( lock_pairs skips middle pair if it creates a cycle
lock_pairs did not correctly lock all non-cyclical pairs
void lock_pairs(void)
{
int winner;
int win_count[MAX];
int temp_win = 0;
for (int i = 0; i < pair_count; i++)
{
locked[ pairs[i].winner ][ pairs[i].loser ] = true;
win_count[ pairs[i].winner ]++;
if (win_count [ pairs[i].winner ] > temp_win )
{
winner = pairs[i].winner;
}
}
for ( int p = 0; p < pair_count; p++)
{
if (win_count[ pairs[p].winner ] == win_count[winner] && pairs[p].winner != winner )
{
for (int i = pair_count - 1; i < -1 ; i--)
{
locked[ pairs[i].winner ][ pairs[i].loser ] = false;
win_count [ pairs[i].winner ]--;
if (pairs[i].winner == winner )
{
win_count[winner]--;
for (int j = 0; j < pair_count; j++)
{
if (win_count[ pairs[j].winner ] > win_count[winner])
{
winner = pairs[j].winner;
}
if (win_count[ pairs[j].winner] == win_count[winner] && pairs[j].winner != winner)
{
break;
}
}
}
else
{
locked[ pairs[i].winner ][ pairs[i].loser ] = true;
}
}
}
}
return;
}
答案 0 :(得分:2)
您可能误解了lock_pairs
背后的逻辑,因为您的功能过于复杂。这就是您要做的-
一个对一个地检查每对,并在必要时将它们锁定
如何知道是否有必要?很简单,您确保将其锁定不构成圆圈
“构成一个圆圈”是什么意思?课程本身对此作了很好的解释。更多信息right there
但基本上,
在以上投票的情况下,这将如何工作?好吧,两人最大的胜利余数是爱丽丝击败鲍勃,因为有7名选民更喜欢爱丽丝,而不是鲍勃(没有其他正面交锋的比赛,胜者超过7名选民)。因此,Alice-Bob箭头首先被锁定到图形中。下一个最大的胜利余地是查理以6-3击败爱丽丝,因此箭号紧随其后。
接下来是鲍勃5-4击败查理。但是请注意:如果我们现在要添加一个从鲍勃到查理的箭头,我们将创建一个循环!由于图表不允许循环,因此我们应该跳过此边缘,而不要将其完全添加到图表中。如果要考虑的箭头更多,我们将转到下一个箭头,但这是最后一个箭头,因此图形已完成。
此分步过程如下所示,最终图形在右侧。
现在真正的交易了,如何将其放入代码中?
像这样-
// Recursive function to check if entry makes a circle
bool makes_circle(int cycle_start, int loser)
{
if (loser == cycle_start)
{
// If the current loser is the cycle start
// The entry makes a circle
return true;
}
for (int i = 0; i < candidate_count; i++)
{
if (locked[loser][i])
{
if (makes_circle(cycle_start, i))
{
// Forward progress through the circle
return true;
}
}
}
return false;
}
本质上,要检查锁定获胜者->失败者是否会绕圈,您走动从失败者开始锁定锁定的条目,并向该失败者拥有的所有候选人赢了。如果您一路走到赢家,如果我见过一个圆圈,那就是一个圆圈。
不过请注意circle_start
,以免引起混淆。仅在那里记住原始的圆起点(即winner
主循环中的lock_pairs
)。在整个递归中,此常数是恒定的。再次记住,我们的目标是遍历 loser
赢得(也被锁定)的所有候选人,并确保所有候选人都不是circle_start
(又名我们将要锁定的winner
)。
因此,该函数完成了所有繁重的工作,您的lock_pairs
函数将非常简单-
// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs()
{
for (int i = 0; i < pair_count; i++)
{
if (!makes_circle(pairs[i].winner, pairs[i].loser))
{
// Lock the pair unless it makes a circle
locked[pairs[i].winner][pairs[i].loser] = true;
}
}
}