您的位置:资讯频道 > 技术文档 > 其 它

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

来源:博客 作者:Edengundam 时间:2008-03-18 点击:395 次
        这个题目上来可能会让人觉得有点束手无策, 但是实际上这道题很简单, 题目允许的范围是75到80分钟, 而歌曲实际上范围还是很大的. 我们只要确定每位歌手只选择两首歌曲即可.

  这道题, 我们可以将歌曲首先按照长度由长到短的顺序进行排列, 这样我们首先选择那些长的歌曲, 再选择短的歌曲来保证最后的播放列表能够满足75到80分钟的要求. 换句话说, 我们首先用较大的石头去填坑, 再用小石头把坑填好. 思路已经有了, 接下来我们需要实现代码:

$songs = Get-Content songlist.csv |`
% { $song = $_.Split(',');
  $hash = New-Object -TypeName HashTable
  $hash.artist = $song[0];
  $hash.name = $song[1];
  $hash.time = [TimeSpan] "00:$($song[2])";
  $hash
}
$songs = $songs | Sort-Object -Property @{e = {$_.time};d=$true}
$atimes = @{}
$low = New-TimeSpan -Minute 75
$high = New-TimeSpan -Minute 80
$total = New-TimeSpan
$cd = $(foreach ($song in $songs)
{
  if (($total -ge $low) -and ($total -le $high)) { break }
  if ($atimes[$song.artist] -lt 2)
  {
   if (($total -lt $low) -and (($total + $song.time) -le $high))
   {
   $total = $total + $song.time;
   $atimes[$song.artist]++;
   $song
   }
 }
}) | Sort-Object -Property @{e={$_.artist}} |`
Select-Object -Property @{n="artist";e={$_.artist}},@{n="name";e={$_.name}},@{n="time";e={$_.time}}
$cd | %{ $_.artist + "`t" + $_.name + "`t" + "$($_.time.Minutes + $_.time.Hours * 60):$('{0:D2}' -f $_.time.Seconds)" }
""
"Total music time: $($total.Minutes + $total.Hours * 60):$('{0:D2}' -f $total.Seconds)"

  每首歌曲被封装在hashtable对象中, 每首歌曲都用一个hashtable表示. 歌曲的长度用TimeSpan来表示, 因为TimeSpan已经完成了很多时间的计算, 我们完全可以不用考虑这些琐碎的细节.

  接下来用Sort-Object对时间进行倒序, 因为使用TimeSpan, 所有PowerShell能够利用该对象完成比较, 我们不需要进行干涉. 每个歌手最多只能选择两首歌曲, 那么建立hash表进行记录是再好不过的决定. 对所有歌曲进行迭代, 如果歌曲加入后, 能够让结果趋向75到80分钟, 并且该名歌手还没有选满2首, 那么将改歌曲输出. 我们还需要主要进行排序工作和时间的统计.

资讯搜索

 

推荐产品

VARCHART XGantt
全球知名的甘特图控件,能够实现如 Microsoft Project 般强大的项目管理功能。
TurboDemo 中文版
TurboDemo - 抓取屏幕截图并通过动态演示示例及手册解释软件、个人电脑应用程序、网站与产品。
BCGControlBar Library .NET Edition
该组件包含大量可自定义程度高、可设计性好的组件,使用户可创建精致美观的图形用户界面。