2008脚本大赛PowerShell高级组Event 3解题及分析

中文题目: http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/chs/aevent3.mspx

英文题解: http://www.microsoft.com/technet/scriptcenter/funzone/games/solutions08/apssol03.mspx

高级组Event 3应该说是一道不错的题目, 只需要细心就能够将题目作对. 优胜的产生方式我们已经非常清楚, 必须要得到50%以上的选票. 如果没有人活得50%以上, 那么这个人就出局了, 但是选票依然有效.

假设我们有一张选票:

B A C D

 如果B在第一轮被淘汰, 那么我们只需要删除所有关于B的选票信息并重新统计:

A C D

如果这次是D被淘汰, 选票只需变更为:

A C

即可, 并不会影响A和C的统计情况.

.Net的提供的System.Collections.ArrayList是完成这个操作的好帮手. 首先我们需要记录一些必要的信息:

$script : candidate  =   " nobody "
$script : loser  =   " nobody "
$running_times   =   4
$script : max_vote  =   0 ;
$script : min_vote  =   0 ;

candidate用来记录一轮中得票最多的人, 他有可能称为最终的获胜者. loser代表本轮将被淘汰的人. max_vote和min_vote分别对应上面两位选手, 用来帮助我们计算得票率. 因为有4个人参加比赛, 因此我们的代码需要执行4次(不是个非常好的设计, 不过it works...).

接下来我们将所有的选票情况转换为我们需要的数据结构:

$votes   =  Get - Content  - Path C :/ Scripts / Votes . txt  |  `
%  {  $vote   =   $_ . Split ( ' , ' );
    
$al   =  New - Object  - TypeName  System . Collections . ArrayList;
    
foreach  ( $v  in  $vote ) { [void]  $al . Add( $v ) }
    
, $al ;
  }

Get-Content每次通过管道传递一行, 然后用Split将4个候选者保存到$vote数组. 然后将其转化为ArrayList. 每个ArrayList有4个候选人的投票顺序. 一个ArrayList代表Votes.txt文件的一行. 最后我们将1200张选票对应的1200个ArrayList存储到$votes中. $votes是一个数组^^

接下来任务很简单, 读取ArrayList第一项, 并进行统计, 看是否有人胜利, 如果没有人得票率超过%50, 那么将loser从所有的选票信息中删除. 然后重复这个过程直到我们的胜利者出现:

While  ( $running_times -- )
{
 
$people   =  @{}
 
foreach  ( $vote  in  $votes )
 {
  
$people [ $vote . GetRange( 0 ,   1 )[ 0 ]] ++ ;
 }
 
$enum   =   $people . GetEnumerator();
 
$sortList   =  $( while  ( $enum . MoveNext()) {  $enum . Current })  |   Sort - Object Value
 
$script : candidate  =   $sortList [ - 1 ] . Key;
 
$script : loser  =   $sortList [ 0 ] . Key;
 
$script : max_vote  =   $sortList [ - 1 ] . Value;
 
$script : min_vote  =   $sortList [ 0 ] . Value;
 
if  (( $script : max_vote  /   $votes . Count)  - gt  0.5 ) { break; }
 
else
 {
  
foreach  ( $vote  in  $votes )
  {
   [void] 
$vote . Remove( " $script:loser " );
  }
 }
}

因为哈希表在PowerShell不能直接进行迭代, 我取得哈希表的迭代器并手动进行, 并将这些内容通过Sort排序, 这样美轮候选者的选票信息就非常容易取得了.

最后是输出胜利者信息, 这里我们省略了小数点, 因此50.2变成了50, 这是因为题目中示例就没有小数点, 也许不是个好的方式吧:

" The winner is $script:candidate with $('{0:P0}' -f ($script:max_vote / $votes.Count)) of the vote. "

不是很难吧? 只需要分析好我们需要处理的情况即可了^_^

 

你可能感兴趣的:(PowerShell新闻)