n 支队伍比赛,分别编号为0,1,2。。。。n-1,已知它们之间的实力对比关系, 存储在一个二维数组w[n][n]中,w[i][j] 的值代表编号为i,j 的队伍中更强的一支。 所以w[i][j]=i 或者j,现在给出它们的出场顺序,并存储在数组order[n]中, 比如order[n] = {4,3,5,8,1......},那么第一轮比赛就是4 对3, 5 对8。....... 胜者晋级,败者淘汰,同一轮淘汰的所有队伍排名不再细分,即可以随便排, 下一轮由上一轮的胜者按照顺序,再依次两两比,比如可能是4 对5,直至出现第一名 编程实现,给出二维数组w,一维数组order 和用于输出比赛名次的数组result[n], 求出result。
1 <?php 2 #比赛晋级问题,已知比赛实力数组w[n][n]和第一轮比赛分配数组order[n] 3 #求比赛名次结果数组r[n] 4 5 #交换 6 function swap(&$a, $i, $j) { 7 $temp = $a[$i]; 8 $a[$i] = $a[$j]; 9 $a[$j] = $temp; 10 } 11 12 function result($w, $order) { 13 $result = array(); 14 while (count($order) > 1) { 15 $len = count($order); 16 $next_order = array(); 17 for ($i = 0; $i < $len; $i += 2) { 18 #最后一个不能配对的人直接轮空 19 if ($i == $len - 1) { 20 $next_order[] = $order[$i]; 21 break; 22 } 23 24 #胜者进入下一轮,负者进入名次数组 25 $next_order[] = $w[$order[$i]][$order[$i + 1]]; 26 $result[] = $w[$order[$i]][$order[$i + 1]] == $order[$i] ? $order[$i + 1] : $order[$i]; 27 } 28 29 #更新比赛分配数组 30 $order = $next_order; 31 } 32 33 $result[] = $order[0]; 34 return $result; 35 } 36 37 #第二种写法,空间复杂度O(1) 38 function result2($w, $order) { 39 $limit = count($order); 40 41 #进行n - 1轮比赛 42 while ($limit > 1) { 43 #确定每轮比赛的结果 44 for ($i = 0, $j = 0; $i < $limit; $i += 2) { 45 $win_inx = ($i == $limit - 1) ? $i : ($w[$order[$i]][$order[$i + 1]] == $order[$i] ? $i : $i + 1); #算出胜者的坐标 46 swap($order, $win_inx, $j); #将胜者排到数组前面 47 $j++; 48 } 49 $limit = $j; 50 } 51 52 return $order; 53 } 54 55 #初始化队伍实力数组和第一轮呢分配数组 56 for ($i = 0; $i < 11; $i++) { 57 $order[] = $i; 58 for ($j = 0; $j < 11; $j++) { 59 $rand = rand(2, 11) % 2; 60 $w[$i][$j] = $rand ? $i : $j; 61 } 62 } 63 64 shuffle($order); 65 66 $result= result($w, $order); 67 print_r($w); 68 echo "<br>"; 69 echo "<br>"; 70 print_r($order); 71 echo "<br>"; 72 echo "<br>"; 73 print_r($result); 74 echo "<br>"; 75 echo "<br>"; 76 print_r(result2($w, $order)); 77 echo "<br>"; 78 echo "<br>"; 79 ?>