最佳升级时间窗

# 1809. 【认证试题】最佳升级时间窗

- 出题人:刘梦丹
- 标签:["滑窗"]
- 难度:中等
- 总分数:200

## 题目描述
有一套系统需升级,为减小系统升级期间的影响,需根据系统过去一段时间内的每小时平均访问数据,来预测最佳升级时间窗。
现给定长度为168(7*24)的整数数组,表示一个周期(假设从周一00:00到周日24:00)的每小时历史数据,最佳升级时间窗选择规则如下:
- 时间窗内累计用户访问量必须小于等于给定的**容忍值**。
- 时间窗必须是连续的x个小时,最大的x即为最佳升级时间窗,且**不超过7*24**。
- 时间窗允许跨周期,例如当前周期的第167小时到下一周期的第166小时,是一个长度为168的时间窗。

请计算最佳升级时间窗,并返回其开始时间和结束时间的数组下标。 如果存在多个最佳升级时间窗时,返回开始时间下标最小的一个。

## 解答要求
时间限制:1000ms, 内存限制:256MB

## 输入
第一行为整数 n ,表示给定的升级影响的容忍值,取值范围:[0, 2^31)。
第二行为7\*24个整数,表示一个周期(7\*24)的每个小时用户访问量,每个值的范围:[0, 2^31)。

## 输出
两个整数,分别表示所计算出的最佳升级时间窗的开始时间下标(包含)和结束时间下标(包含),不存在时返回`-1 -1`。

## 样例
### 输入样例 1:
```
6
1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 12 11 10 9 8 7 6 5 4 3 2 1
```
### 输出样例 1:
```
22 25

```
### 输入样例 2:
```
167
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 167 1
```
### 输出样例 2:
```
167 165
```
### 输入样例 3:
```
200
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
```
### 输出样例 3:
```
0 167
```
## 提示
**答题要求:结果可信和过程可信同样重要,您编写的代码需要符合可信的要求(包括通用编码规范、安全编码规范和圈复杂度)。**






/*
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: 考生实现代码
* Note: 缺省代码仅供参考,可自行决定使用、修改或删除
* 只能import Go标准库
*/
package main

import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)

// 待实现函数,在此函数中填入答题代码
func getBestTimeWindow(usersPerHour []int, threshold int) []int {
usersPerHour = append(usersPerHour, usersPerHour...)
result := make([]int, 2, 2)
result[0], result[1] = -1, -1
length := len(usersPerHour)
lastWin := -1
win := 0
for i := 0; i < length; i++ {
nowThreshold := 0
for j := i; j < length; j++ {
nowThreshold += usersPerHour[j]
if nowThreshold > threshold {
break
}
win = j - i
if nowThreshold <= threshold && win > lastWin {
lastWin = win
result[0], result[1] = i, j
}
}
}
if result[1] > len(usersPerHour)/2-1 {
result[1] -= len(usersPerHour) / 2
}
return result
}

func main() {
reader := bufio.NewReader(os.Stdin)
ints, err := readIntSlice(reader, " ")
if err != nil {
return
}
threshold := ints[0]
usersPerHour, err := readIntSlice(reader, " ")
if err != nil {
return
}
result := getBestTimeWindow(usersPerHour, threshold)
fmt.Print(result[0], result[1])
}

func readIntSlice(reader *bufio.Reader, sep string) ([]int, error) {
lineBuf, err := reader.ReadString('\n')
if err != nil && err != io.EOF {
return nil, fmt.Errorf(err.Error())
}

lineBuf = strings.TrimRight(lineBuf, "\r\n")
line := strings.Split(lineBuf, sep)
var result []int
for _, v := range line {
i, err := strconv.ParseInt(v, 10, 32)
if err != nil {
return nil, fmt.Errorf(err.Error())
}
result = append(result, int(i))
}
return result, nil
}







````
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
* Description: 考生实现代码
* Note: 缺省代码仅供参考,可自行决定使用、修改或删除
* 只能import Go标准库
*/
package main

import (
"bufio"
"fmt"
"io"
"math"
"os"
"strconv"
"strings"
)

func getAllWindowsNumSum(userPerHours []int,begin int,end int) int {
total := 0
for i:= begin;i<end;i++{
total += userPerHours[i]
}
return total
}

func getBestTimeWindowByTwoFor(userPerHours []int, threshold int) []int{
lens := len(userPerHours)
maxDeltaHour := 0
var maxStayArr []int
maxStayValue := make(map[int][]int,2)
for i := 0;i < lens;i++{
for j := i; j < lens;j++{
totalSum := getAllWindowsNumSum(userPerHours,i,j)
if totalSum <= threshold {
//记录下合适的,然后再筛选
tempDeltaHour := j - i
if maxDeltaHour < tempDeltaHour {
maxDeltaHour = tempDeltaHour
maxStayArr = append(maxStayArr, i)
maxStayArr = append(maxStayArr, j)
maxStayValue[maxDeltaHour] = maxStayArr
maxStayArr = []int{}
}
}
}
}
if maxDeltaHour > 0{
return []int{maxStayValue[maxDeltaHour][0],maxStayValue[maxDeltaHour][1]}
}
return []int{-1,-1}
}


func getBestTimeWindowByTwoForTime(userPerHours []int,threshold int) []int{
userPerHours = append(userPerHours,userPerHours...)
result := make([]int,2,2)
result[0],result[1] = -1,-1
lens := len(userPerHours)
lastWin := -1
win := 0
for i:= 0;i<lens;i++ {
newThreshold := 0
for j:= i;j<lens;j++ {
newThreshold += userPerHours[j]
if newThreshold > threshold {
break
}
win = j - i
if newThreshold <= threshold && win > lastWin && win < 168{
lastWin = win
result[0],result[1] = i,j
}
}
}
if result[1] > len(userPerHours)/2 - 1 {
result[1] -= len(userPerHours)/2
}
return result
}

func getBestTimeWindow(userPerHours []int,threshold int) []int {
result := []int{-1,-1}
windowMaps := map[int]int{}
var windValue int64
var right,left int
userPerHours = append(userPerHours,userPerHours...)
maxLen := 0
for right < len(userPerHours){
//1 准备入窗
insertVal := userPerHours[right]
windValue += int64(insertVal)
//2 进行一系列更新
//debug 输出
fmt.Printf("******************windown:(%d,%d)**windvalue:(%d)*******maxLen:(%d)*************\r\n",left,right,windValue,maxLen)
if windValue <= int64(threshold){
windowMaps[left] = right
if right - left >= maxLen && windValue < 168{
maxLen = right - left
result[0] = left
result[1] = right%168
}
}else{
windValue -= int64(userPerHours[left])
left ++
}
right++
}
return result
}

func getBestTimeWindowTest(usersPerHour []int, threshold int) []int {
result := []int{-1, -1}
windowMaps := map[int]int{}
var windValue int64
var left,right int
usersPerHour = append(usersPerHour,usersPerHour...)
for right<len(usersPerHour){
windValue += int64(usersPerHour[right])
if windValue <= int64(threshold){
windowMaps[left] = right
}else{
windValue -= int64(usersPerHour[left])
left++
}
right++
}
wind := math.MinInt32
for key,value := range windowMaps{
if value - key > wind{
result = []int{key,value}
wind = value - key
}
}
if result[1] >= 168{
result[1] = result[1] % 168
}
return result
}

func readInitSlice(reader *bufio.Reader,sep string) ([]int,error) {
lineBuf,err := reader.ReadString('\n')
if err != nil && err != io.EOF{
return nil,fmt.Errorf(err.Error())
}
lineBuf = strings.TrimRight(lineBuf,"\r\n")
line := strings.Split(lineBuf,sep)
var result []int
for _,v := range line {
i,err := strconv.ParseInt(v,10,32)
if err != nil {
return nil,fmt.Errorf(err.Error())
}
result = append(result,int(i))
}
return result,nil
}

func main() {
reader := bufio.NewReader(os.Stdin)
//获得容忍度和周期值
ints,err := readInitSlice(reader," ")
if err != nil{
return
}
threshold := ints[0]
userPerHours,err := readInitSlice(reader," ")
if err != nil{
return
}
result := getBestTimeWindow(userPerHours, threshold)
fmt.Println(result[0],result[1])

}

```




posted @ 2022-03-10 22:30  易先讯  阅读(413)  评论(0编辑  收藏  举报