首页 > 试题广场 >

能量共振

[编程题]能量共振
  • 热度指数:1290 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
在一项对时空连续体的高维研究中,科学家们发现了一种被称为“零点能量共振”的现象。
这种现象表现为在一段连续的时间序列能量读数中,存在一个可以被精确分割成两个连续部分、且每个部分的能量扰动总和都恰好为零的区间。
这种特殊的“对称”共振区间被认为是时空稳定的关键指标。

给定一个记录了 N 个连续时间点能量扰动值的数组 A
数组中的元素为带符号整数。
你的任务是找出其中最短的、能够表现出“零点能量共振”的子数组。

一个子数组被称为“可对称分割”,如果它能被分割成两个连续的子数组,且这两个子数组的元素和都为零。

形式化地说,对于一个子数组 A[i \dots j-1](下标从 ij-1),如果存在一个分割点 k(其中 i < k < j),使得:
\sum_{p=i}^{k-1} A[p] = 0 并且 \sum_{p=k}^{j-1} A[p] = 0
那么,这个子数组 A[i \dots j-1] 就是一个满足条件的共振区间。

你的目标是找到所有这类共振区间中,长度最短的一个或多个。
你需要报告这个最短的长度,以及具有该最短长度的共振区间的数量。

输入描述:
输入包含两行:

第一行是一个整数 N,代表时间序列的长度(数组 A 的元素数量)。
1 \le N \le 10^6

第二行包含 N 个整数 X_i,代表数组 A 的元素。
-10000 \le X_i \le 10000


输出描述:
输出一行,包含两个整数,由空格隔开:
1. 满足条件的最短子数组的长度。
2. 具有该最短长度的子数组的个数

如果不存在任何满足条件的子数组,则输出 `-1 -1`。
示例1

输入

5
1 -1 1 -1 1

输出

4 2
示例2

输入

7
0 100 1 300 2 10 0

输出

-1 -1
示例3

输入

7
100 1 -1 3 -2 -1 100

输出

5 1

备注:
本题由牛友@Charles 整理上传
把相同的前缀和放到一起,分别遍历即可得出答案
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
)

func main() {
    reader:=bufio.NewReader(os.Stdin)
    writer:=bufio.NewWriter(os.Stdout)
    defer writer.Flush()
    var n int
    fmt.Fscan(reader,&n)
    pre:=make(map[int][]int,0)
    pre[0]=[]int{-1}
    temp:=0
    for i:=0;i<n;i++{
        var a int
        fmt.Fscan(reader,&a)
        temp+=a
        if _,e:=pre[temp];!e{
            pre[temp]=make([]int,0)
        }
        pre[temp]=append(pre[temp], i)
    }
    minlenth,minnumber:=math.MaxInt64,0
    for _,pres:=range pre{
        if len(pres)>=3{
            for i:=0;i<len(pres)-2;i++{
                if pres[i+2]-pres[i]<minlenth{
                    minlenth=pres[i+2]-pres[i]
                    minnumber=1
                }else if pres[i+2]-pres[i]==minlenth{
                    minnumber++
                }
            }
        }
    }
    if minnumber==0{
        fmt.Fprint(writer,-1,-1)
    }else{
        fmt.Fprint(writer,minlenth,minnumber)
    }
}


发表于 2026-04-15 15:05:29 回复(0)