2026/5/21 17:35:05
网站建设
项目流程
个人承接网站开发项目,百度推广投诉中心,wordpress标记已读,网站如何微信支付最佳升级时间窗 2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型 华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录#xff5c;机考题库 算法考点详解
题目描述
有一套系统需升级#xff0c;为减小系统升级期间的影响#xff0c;需…最佳升级时间窗2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录机考题库 算法考点详解题目描述有一套系统需升级为减小系统升级期间的影响需根据系统过去一段时间内的每小时平均访问数据来预测最佳升级时间窗。现给长度为1687*24的整数数组表示一个周期假设从周一00:00到周日24:00的每小时历史数据最佳升级时间窗选择规则如下1时间窗内累计用户访问量必须小于等于给定的容忍值。2时间窗必须是连续的x个小时最大的x即为最佳升级时间窗且不超过7*24.3时间窗允许跨周期例如当前周期的第167小时到下一周期的第166小时是一个长度为168的时间窗。请计算最佳升级时间窗并返回其开始时间和结束时间的数组下标。如果存在多个最佳升级时间窗返回开始时间下标最小的一个。输入描述第一行为整数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输出22 25说明最佳升级窗口为2 1 1 2题解思路滑动窗口这类题就是典型使用滑动窗口解决的题然后思考怎么解决题目提到的时间窗允许跨周期的问题对于这类首尾可以连接的问题可以将数组进行扩容168*2将数组重复一次跨周期的窗口就可以变为普通连续子数组问题。接下来就是正常滑动窗口处理逻辑,定义左边界left 0, right 0, 窗口和windowsSum 0maxLen 0, resLeft -1, resRight -1, 接下来就是循环移动右边界每次执行以下操作windowsSum seq[i]如果windowsSum n,不断收缩左边界直到windowSum n结束收缩边界每次执行windowsSum - seq[left], left经过上面就会得到一个合法的窗口计算长度为len right - left 1, 然后根据与maxLen更新结果即可。这里有个易错点之前将原数组扩容了可能存在n sum(originalSeq)这样长度可以超过168所以当len 168可以直接退出滑动窗口逻辑。优化点:如果当left 168也可以提前退出滑动窗口逻辑因为这里又进入了第一个周期一样的逻辑没必要重复找。当前不做这个优化这道题也不会超时。执行3的逻辑之后此时根据maxLen的值输出结果maxLen 0: 说明不存在这样窗口直接输出-1 -1maxLen !0: 说明存在窗口此时需要输出(resLeft % 168) (resRight % 168),%128主要是处于跨周期的情况要保证输出的为[0,167]范围。c#includeiostream #includevector #includestring #include utility #include sstream #includealgorithm #includecmath #includemap using namespace std; int main() { long n; cin n; // 由于可以首尾相连直接将数组重复一次这样跨周期的窗口就可以变为普通连续子数组问题 vectorlong seq(168 * 2); for (int i 0; i 168; i) { cin seq[i]; seq[i 168] seq[i]; } int maxLen 0; int resLeft -1, resRight -1; long windowSum 0; int left 0; for (int right 0; right 168 * 2; right) { windowSum seq[right]; // 保证窗口和不超过容忍值 while (windowSum n) { windowSum - seq[left]; left; } // 和第一个周期重复了 if (left 168) { break; } int len right - left 1; if (len maxLen) { maxLen len; resLeft left; resRight right; } // 已经达到最大周期可以直接退出 if (len 168) { break; } } if (maxLen 0) { cout -1 -1; }else { cout resLeft % 168 resRight % 168; } return 0; }JAVAimport java.util.*; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); long n sc.nextLong(); // 由于可以首尾相连直接将数组重复一次这样跨周期的窗口就可以变为普通连续子数组问题 long[] seq new long[168 * 2]; for (int i 0; i 168; i) { seq[i] sc.nextLong(); seq[i 168] seq[i]; } int maxLen 0; int resLeft -1, resRight -1; long windowSum 0; int left 0; for (int right 0; right 168 * 2; right) { windowSum seq[right]; // 保证窗口和不超过容忍值 while (windowSum n) { windowSum - seq[left]; left; } // 和第一个周期重复了 if (left 168) { break; } int len right - left 1; if (len maxLen) { maxLen len; resLeft left; resRight right; } // 已经达到最大周期可以直接退出 if (len 168) { break; } } if (maxLen 0) { System.out.println(-1 -1); } else { System.out.println(resLeft % 168 resRight % 168); } } }Pythonnint(input())arrlist(map(int,input().split()))# 由于可以首尾相连重复一次seqarrarr maxLen0resLeft-1resRight-1windowSum0left0forrightinrange(len(seq)):windowSumseq[right]# 保证窗口和不超过容忍值whilewindowSumn:windowSum-seq[left]left1# 和第一个周期重复了ifleft168:breaklengthright-left1iflengthmaxLen:maxLenlength resLeftleft resRightright# 已经达到最大周期可以直接退出iflength168:breakifmaxLen0:print(-1 -1)else:print(resLeft%168,resRight%168)JavaScriptletinput[];require(readline).createInterface({input:process.stdin,output:process.stdout}).on(line,lineinput.push(line)).on(close,(){letnparseInt(input[0]);letarrinput[1].split( ).map(Number);// 由于可以首尾相连重复一次letseqarr.concat(arr);letmaxLen0;letresLeft-1,resRight-1;letwindowSum0;letleft0;for(letright0;rightseq.length;right){windowSumseq[right];// 保证窗口和不超过容忍值while(windowSumn){windowSum-seq[left];left;}// 和第一个周期重复了if(left168)break;letlenright-left1;if(lenmaxLen){maxLenlen;resLeftleft;resRightright;}// 已经达到最大周期可以直接退出if(len168)break;}if(maxLen0){console.log(-1 -1);}else{console.log(resLeft%168,resRight%168);}});Gopackagemainimport(fmt)funcmain(){varnint64fmt.Scan(n)seq:make([]int64,168*2)fori:0;i168;i{fmt.Scan(seq[i])seq[i168]seq[i]// 重复一次}maxLen:0resLeft,resRight:-1,-1varwindowSumint640left:0forright:0;right168*2;right{windowSumseq[right]// 保证窗口和不超过容忍值forwindowSumn{windowSum-seq[left]left}// 和第一个周期重复了ifleft168{break}length:right-left1iflengthmaxLen{maxLenlength resLeftleft resRightright}// 已经达到最大周期可以直接退出iflength168{break}}ifmaxLen0{fmt.Println(-1 -1)}else{fmt.Println(resLeft%168,resRight%168)}}