Don't Break the Nile 2

本文介绍了一个关于在尼罗河上建造桥梁的算法挑战赛题解析,通过定义桥梁之间的距离来寻找最小切割值,使用Scala实现了一种解决方案,包括读取输入文件、构建建筑物模型并计算它们之间的最短距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package codejam.year2004.round2

import scala.io.Source
import scala.collection.mutable.Queue

object DontBreakTheNile2 extends App {

  val file = "src/main/scala/codejam/year2004/round2/C-large-practice.in"

  val lines = Source.fromFile(file).getLines()

  val T = lines.next().toInt

  def process(t: Int): Unit =
    if (t <= T) {
      val line = lines.next().split("\\s+").map(_.toInt)
      val w = line(0)
      val h = line(1)
      val b = line(2)

      trait Block {
        def dist(that: Block): Int
      }
      case class Building(x0: Int, y0: Int, x1: Int, y1: Int) extends Block {

        private def distX(that: Building) =
          if (x0 <= that.x1 && that.x0 <= x1) 0
          else if (x1 < that.x0) that.x0 - x1 - 1
          else x0 - that.x1 - 1

        private def distY(that: Building) =
          if (y0 <= that.y1 && that.y0 <= y1) 0
          else if (y1 < that.y0) that.y0 - y1 - 1
          else y0 - that.y1 - 1

        def dist(that: Block) = that match {
          case LeftBank => x0
          case RightBank => w - 1 - x1
          case b: Building => distX(b) max distY(b)
        }
      }
      case object LeftBank extends Block {
        def dist(that: Block) = that match {
          case b: Building => b.dist(this)
          case RightBank => w
        }
      }
      case object RightBank extends Block {
        def dist(that: Block) = that match {
          case b: Building => b.dist(this)
          case LeftBank => w
        }
      }

      def readBlock(i: Int, blocks: Map[Int, Block]): Map[Int, Block] =
        if (i == b + 2) blocks
        else if (i == b + 1) readBlock(i + 1, blocks + (i -> RightBank))
        else if (i == b) readBlock(i + 1, blocks + (i -> LeftBank))
        else {
          val cord = lines.next().split("\\s+").map(_.toInt)
          readBlock(i + 1, blocks + (i -> Building(cord(0), cord(1), cord(2), cord(3))))
        }

      val blocks = readBlock(0, Map.empty)
      val grid = Array.fill(b + 2)(Array.fill(b + 2)(0))

      for {
        i <- 0 until b + 2
        a = blocks(i)
        j <- (i + 1) until b + 2
        b = blocks(j)
        d = a.dist(b)
      } {
        grid(i)(j) = d
        grid(j)(i) = d
      }

      def min(xs: Array[Int], i: Int, m: Int, checked: Set[Int]): Int =
        if (i >= xs.length) m
        else {
          if (checked.contains(i)) min(xs, i + 1, m, checked)
          else if (m < 0 || xs(m) > xs(i)) min(xs, i + 1, i, checked)
          else min(xs, i + 1, m, checked)
        }

      def bfs(dist: Array[Int], checked: Set[Int]): Int = {
        val i = min(dist, 0, -1, checked)
        if (i == b + 1) dist(i)
        else {
          val v = dist(i)
          for {
            j <- 0 until b + 2
            if (j != i && !checked.contains(j))
          } {
            if (v + grid(i)(j) < dist(j)) {
              dist(j) = v + grid(i)(j)
            }
          }
          bfs(dist, checked + i)
        }
      }

      val dist = Array.fill(b + 2)(w)
      dist(b) = 0

      val minCut = bfs(dist, Set.empty)

      println(s"Case #$t: $minCut")

      process(t + 1)
    }

  process(1)

}  
### 对Nile数据集进行平稳性检验 对于时间序列分析中的平稳性检验,ADF (Augmented Dickey-Fuller) 测试是一种常用方法。该测试可以用于检测给定的时间序列是否存在单位根,从而判断其是否为平稳过程。 在R环境中执行ADF测试并展示结果如下: ```r library(tseries) adf.test(Nile, alternative="stationary", k=0)[^1] ``` 上述命令通过`tseries`库调用了`adf.test()`函数来对Nile数据集进行了ADF测试。参数设置中指定了备择假设(`alternative`)为"stationary"(即认为序列是平稳的),以及滞后阶数(`k`)设为了零表示不考虑额外延迟项的影响。 如果p-value小于显著水平(通常取0.05),则拒绝存在单位根这一原假设,意味着此时间序列为平稳;反之,则接受原假设表明它不是平稳序列。 除了ADF测试之外,还可以利用KPSS(Kwiatkowski–Phillips–Schmidt–Shin)测试来进行另一种形式上的平稳性评估,在某些情况下两者可能会给出不同的结论。以下是使用KPSS测试的例子: ```r kpss.test(Nile, null="Level") ``` 这里选择了以水平作为零假设的形式(null="Level"),这意呸着当无法拒绝零假设时,说明时间序列围绕常数值波动而保持稳定状态。同样地,依据返回的结果里所含有的P值大小决定能否推翻关于非平稳性的断言。 #### 使用Python实现相同功能 同样的操作也可以借助Python完成,下面给出了相应的代码片段: ```python from statsmodels.tsa.stattools import adfuller, kpss import pandas as pd nile_data = pd.read_csv('path_to_nile_dataset.csv') # 需要先下载好Nile数据集文件 result_adf = adfuller(nile_data['flow'], autolag='AIC') print(f'ADF Statistic: {result_adf[0]}') print(f'p-value: {result_adf[1]}') result_kpss = kpss(nile_data['flow']) print(f'KPSS Statistic: {result_kpss[0]}') print(f'p-value: {result_kpss[1]}') ``` 这段脚本首先导入了必要的统计工具包,并读入了本地存储的Nile流量数据表单。接着分别应用了ADFuller和KPSS两种算法计算对应的统计量及其伴随概率(p-values),最后打印出来供进一步解释之用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值