做平面找那些网站找活,广告策划书的格式,商城网站建设企业,郑州最新情况采样过滤 2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 200分题型 华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录#xff5c;机考题库 算法考点详解
题目描述
在做物理实验时#xff0c;为了计算物体移动的速率#xff0c;通过相机等工…采样过滤2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 200分题型华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录机考题库 算法考点详解题目描述在做物理实验时为了计算物体移动的速率通过相机等工具周期性的采样物体移动距离。由于工具故障采样数据存在误差甚至错误的情况。需要通过一个算法过滤掉不正确的采样值。不同工具的故障模式存在差异算法的各类门限会根据工具类型做相应的调整。请实现一个算法计算出给定一组采样值中正常值的最长连续周期。判断第 i 个周期的采样数据 S[i] 是否正确的规则如下假定物体移动速率不超过10个单元前一个采样周期 S[i-1] )S[i] 0即为错误值S[i] S[i-1]即为错误值S[i] - S[i-1] 10即为错误值其它情况为正常值判断工具是否故障的规则如下在M个周期内采样数据为错误值的次数为T次数可以不连续则工具故障。判断故障恢复的条件如下产生故障后的P个周期内采样数据一直为正常值则故障恢复。错误采样数据的处理方式:检测到故障后丢弃从故障开始到故障恢复的采样数据。在检测到工具故障之前错误的采样数据则由最近一个正常值代替如果前面没有正常的采样值则丢弃此采样数据。给定一段周期的采样数据列表S计算正常值的最长连续周期。输入描述故障确认周期数和故障次数门限分别为M和T故障恢复周期数为P。第 i 个周期检测点的状态为Si输入为两行格式如下M T P S1 S2 S3 ...M、T和P的取值范围为[1, 100000]Si取值范围为[0, 100000]i 从0开始编号输出描述一行输出正常值的最长连续周期用例1输入10 6 3 -1 1 2 3 100 10 13 9 10输出8说明S[0]S[4]S[7]S[8]为错误值。S[0]之前没有正常的采样数据丢弃S[0]。S[4]和S[7]不满足故障条件此值分别由S[3]和S[6]代替即S[4]为3S[7]为13。替换后S[8]小于S[7]也是错误值。题解思路模拟这道题就是细节比较多实际难度不是很高。简单逻辑如下:可以使用一个双端队列deque存储发生错误采样位置序号用来处理判定故障发生的情况。额外注意判断故障前应先移除队首小于等于 i -m的序号因为题目要求的判断故障限制在m大小的窗口。接下来定义hasLastValid表示这个采样之前是否有正常采样值lastValidValue记录最近正常采样值。currentLen 0表示当前正常连续周期数,maxCurrentLen 0记录最大正常连续周期数。接下来就是循环遍历输入检测序列首先判断当前序列current是否属于发生错误(这部分参照下面代码)如果没有发生错误执行currentLen 1,hasLastValid true,lastValidValue current如果发生错误将当前序号插入deque.然后分类处理如果当前dequeu.size() t,说明发生故障进入故障恢复阶段。如果当前dequeu.size() t,此时没有发生故障分情况处理,以这个作为出发点在检测到工具故障之前错误的采样数据则由最近一个正常值代替如果前面没有正常的采样值则丢弃此采样数据。hasLastValid true情况下, 执行currentLen 1, current lastValid操作。hasLastValid false情况下, 不执行操作因为不会影响currentLen按照3的逻辑处理之后记录下的maxLen就是结果。c#includeiostream #includevector #includestring #include utility #include sstream #includealgorithm #includecmath #includemap #includedeque using namespace std; // 通用 切割函数 函数 将字符串str根据delimiter进行切割 vectorint split(const string str, const string delimiter) { vectorint result; size_t start 0; size_t end str.find(delimiter); while (end ! string::npos) { result.push_back(stoi(str.substr(start, end - start))); start end delimiter.length(); end str.find(delimiter, start); } // 添加最后一个部分 result.push_back(stoi(str.substr(start))); return result; } // 检验当前值是否合法 bool check(int cureent, bool hasLastValid, int lastValidValue) { if (cureent 0) return false; if (hasLastValid) { if (cureent lastValidValue) return false; if (cureent - lastValidValue 10) return false; } return true; } int main() { // 窗口大小 窗口出现次数 恢复 int m, t, p; cin m t p; // 忽略换行符 cin.ignore(); string input; getline(cin, input); vectorint seq split(input, ); int n seq.size(); // 最近一个有效正常值 bool hasLastValid false; int lastValidValue 0; // 当前正常连续周期数 int currentLen 0; // 最大正常连续周期数 int maxLen 0; // 最近 M 个周期内的错误位置 dequeint errorWindow; for (int i 0; i n; ) { int current seq[i]; bool isNormal check(current, hasLastValid, lastValidValue); // 移除超过m窗口的错误 while (!errorWindow.empty() errorWindow.front() i - m) { errorWindow.pop_front(); } // 正常值 if (isNormal) { hasLastValid true; lastValidValue current; currentLen; maxLen max(currentLen, maxLen); // 异常值 } else { // 加入队列中 errorWindow.push_back(i); // 没有发生故障 if (errorWindow.size() t) { // 并且前面有效值 没有的话应该直接丢弃不会加长度不处理 if (hasLastValid) { seq[i] lastValidValue; currentLen; maxLen max(currentLen, maxLen); } // 从这里发生故障 } else { // 按照这里逻辑直接进行故障恢复 int j i 1; bool recoveryHasLastValid false; int recoveryLastValidValue 0; // 连续正常区间个数 int pcount 0; while (j n pcount p) { int recoveryCurrent seq[j]; bool recoveryIsNormal check(recoveryCurrent, recoveryHasLastValid, recoveryLastValidValue); if (recoveryIsNormal) { pcount; recoveryHasLastValid true; recoveryLastValidValue recoveryCurrent; // 连续被终止 } else { pcount 0; recoveryHasLastValid false; recoveryLastValidValue 0; } j; } // 全部丢弃 currentLen 0; errorWindow.clear(); // 认定之前没有合法值 hasLastValid false; lastValidValue 0; i j - 1; } } i; } cout maxLen endl; return 0; }JAVAimport java.util.*; public class Main { // 检验当前值是否合法 static boolean check(int current, boolean hasLastValid, int lastValidValue) { if (current 0) return false; if (hasLastValid) { if (current lastValidValue) return false; if (current - lastValidValue 10) return false; } return true; } public static void main(String[] args) { Scanner sc new Scanner(System.in); // 窗口大小 窗口出现次数 恢复 int m sc.nextInt(); int t sc.nextInt(); int p sc.nextInt(); sc.nextLine(); // 忽略换行 // 读取采样序列 String line sc.nextLine(); String[] parts line.split( ); int n parts.length; int[] seq new int[n]; for (int i 0; i n; i) seq[i] Integer.parseInt(parts[i]); // 最近一个有效正常值 boolean hasLastValid false; int lastValidValue 0; // 当前正常连续周期数 int currentLen 0; // 最大正常连续周期数 int maxLen 0; // 最近 M 个周期内的错误位置 DequeInteger errorWindow new LinkedList(); for (int i 0; i n; ) { int current seq[i]; boolean isNormal check(current, hasLastValid, lastValidValue); // 移除超过m窗口的错误 while (!errorWindow.isEmpty() errorWindow.peekFirst() i - m) { errorWindow.pollFirst(); } // 正常值 if (isNormal) { hasLastValid true; lastValidValue current; currentLen; maxLen Math.max(currentLen, maxLen); // 异常值 } else { // 加入队列中 errorWindow.addLast(i); // 没有发生故障 if (errorWindow.size() t) { // 并且前面有效值 没有的话应该直接丢弃不会加长度不处理 if (hasLastValid) { seq[i] lastValidValue; currentLen; maxLen Math.max(currentLen, maxLen); } // 从这里发生故障 } else { // 按照这里逻辑直接进行故障恢复 int j i 1; boolean recoveryHasLastValid false; int recoveryLastValidValue 0; // 连续正常区间个数 int pcount 0; while (j n pcount p) { int recoveryCurrent seq[j]; boolean recoveryIsNormal check(recoveryCurrent, recoveryHasLastValid, recoveryLastValidValue); if (recoveryIsNormal) { pcount; recoveryHasLastValid true; recoveryLastValidValue recoveryCurrent; // 连续被终止 } else { pcount 0; recoveryHasLastValid false; recoveryLastValidValue 0; } j; } // 全部丢弃 currentLen 0; errorWindow.clear(); // 认定之前没有合法值 hasLastValid false; lastValidValue 0; i j - 1; } } i; } System.out.println(maxLen); } }Pythonimportsysfromcollectionsimportdeque# 检验当前值是否合法defcheck(current,has_last_valid,last_valid_value):# 当前值 0 为错误值ifcurrent0:returnFalseifhas_last_valid:# 如果有上一个正常值当前值小于上一个也为错误ifcurrentlast_valid_value:returnFalse# 当前值超过上一个正常值 10也为错误ifcurrent-last_valid_value10:returnFalsereturnTruedefmain():# 窗口大小 m窗口出现次数 t恢复周期 pm,t,pmap(int,sys.stdin.readline().split())# 读取采样序列seqlist(map(int,sys.stdin.readline().split()))nlen(seq)# 最近一个有效正常值has_last_validFalselast_valid_value0# 当前正常连续周期数current_len0# 最大正常连续周期数max_len0# 最近 M 个周期内的错误位置error_windowdeque()i0whilein:currentseq[i]is_normalcheck(current,has_last_valid,last_valid_value)# 移除超过 m 窗口的错误whileerror_windowanderror_window[0]i-m:error_window.popleft()# 正常值ifis_normal:has_last_validTruelast_valid_valuecurrent current_len1max_lenmax(max_len,current_len)else:# 异常值加入队列error_window.append(i)# 没有发生故障iflen(error_window)t:# 前面有正常值用最近正常值替换ifhas_last_valid:seq[i]last_valid_value current_len1max_lenmax(max_len,current_len)# 前面没有正常值直接丢弃不增加长度else:# 从这里发生故障寻找恢复ji1recovery_has_last_validFalserecovery_last_valid_value0pcount0whilejnandpcountp:recovery_currentseq[j]recovery_is_normalcheck(recovery_current,recovery_has_last_valid,recovery_last_valid_value)ifrecovery_is_normal:pcount1recovery_has_last_validTruerecovery_last_valid_valuerecovery_currentelse:pcount0recovery_has_last_validFalserecovery_last_valid_value0j1# 故障期间丢弃current_len0error_window.clear()has_last_validFalselast_valid_value0ij-1# 跳过故障恢复阶段i1print(max_len)if__name____main__:main()JavaScript// Node 链表节点classNode{constructor(val){this.valval;this.nextnull;this.prevnull;}}// 双端链表 dequeclassDeque{constructor(){this.headnull;this.tailnull;this.size0;}pushBack(val){letnodenewNode(val);if(!this.tail){this.headthis.tailnode;}else{this.tail.nextnode;node.prevthis.tail;this.tailnode;}this.size;}popFront(){if(!this.head)returnnull;letvalthis.head.val;this.headthis.head.next;if(this.head)this.head.prevnull;elsethis.tailnull;this.size--;returnval;}front(){returnthis.head?this.head.val:null;}getSize(){returnthis.size;}}// ACM 模式constreadlinerequire(readline);constrlreadline.createInterface({input:process.stdin,output:process.stdout});letinputLines[];rl.on(line,(line){inputLines.push(line);}).on(close,(){// 解析输入const[m,t,p]inputLines[0].split( ).map(Number);constseqinputLines[1].split( ).map(Number);constnseq.length;// 检验当前值是否合法functioncheck(current,hasLastValid,lastValidValue){if(current0)returnfalse;if(hasLastValid){if(currentlastValidValue)returnfalse;if(current-lastValidValue10)returnfalse;}returntrue;}// 最近一个有效正常值lethasLastValidfalse;letlastValidValue0;// 当前正常连续周期数letcurrentLen0;// 最大正常连续周期数letmaxLen0;// 最近 M 个周期内的错误位置用自定义 deque 保证前端删除 O(1) 实际机考可能并没这么大数据量可以先用数组模拟试试leterrorWindownewDeque();leti0;while(in){letcurrentseq[i];letisNormalcheck(current,hasLastValid,lastValidValue);// 移除超过 m 窗口的错误while(errorWindow.getSize()0errorWindow.front()i-m){errorWindow.popFront();}// 正常值if(isNormal){hasLastValidtrue;lastValidValuecurrent;currentLen;maxLenMath.max(maxLen,currentLen);}else{// 异常值加入队列中errorWindow.pushBack(i);// 没有发生故障if(errorWindow.getSize()t){if(hasLastValid){seq[i]lastValidValue;currentLen;maxLenMath.max(maxLen,currentLen);}}else{// 从这里发生故障寻找恢复letji1;letrecoveryHasLastValidfalse;letrecoveryLastValidValue0;letpcount0;while(jnpcountp){letrecoveryCurrentseq[j];letrecoveryIsNormalcheck(recoveryCurrent,recoveryHasLastValid,recoveryLastValidValue);if(recoveryIsNormal){pcount;recoveryHasLastValidtrue;recoveryLastValidValuerecoveryCurrent;}else{pcount0;recoveryHasLastValidfalse;recoveryLastValidValue0;}j;}// 故障期间丢弃currentLen0;errorWindownewDeque();hasLastValidfalse;lastValidValue0;ij-1;}}i;}console.log(maxLen);});Gopackagemainimport(bufiocontainer/listfmtosstrconvstrings)// 检验当前值是否合法funccheck(currentint,hasLastValidbool,lastValidValueint)bool{ifcurrent0{returnfalse}ifhasLastValid{ifcurrentlastValidValue{returnfalse}ifcurrent-lastValidValue10{returnfalse}}returntrue}funcmain(){reader:bufio.NewReader(os.Stdin)// 窗口大小 窗口出现次数 恢复line1,_:reader.ReadString(\n)parts:strings.Fields(line1)m,_:strconv.Atoi(parts[0])t,_:strconv.Atoi(parts[1])p,_:strconv.Atoi(parts[2])line2,_:reader.ReadString(\n)seqParts:strings.Fields(line2)n:len(seqParts)seq:make([]int,n)fori:0;in;i{seq[i],_strconv.Atoi(seqParts[i])}// 最近一个有效正常值hasLastValid:falselastValidValue:0currentLen:0maxLen:0// 最近 M 个周期内的错误位置用 container/list 高效 O(1) 删除前端errorWindow:list.New()i:0forin{current:seq[i]isNormal:check(current,hasLastValid,lastValidValue)// 移除超过 m 窗口的错误forerrorWindow.Len()0{front:errorWindow.Front()iffront.Value.(int)i-m{errorWindow.Remove(front)}else{break}}// 正常值ifisNormal{hasLastValidtruelastValidValuecurrent currentLenifcurrentLenmaxLen{maxLencurrentLen}}else{// 异常值加入队列中errorWindow.PushBack(i)iferrorWindow.Len()t{ifhasLastValid{seq[i]lastValidValue currentLenifcurrentLenmaxLen{maxLencurrentLen}}}else{// 故障处理寻找恢复j:i1recoveryHasLastValid:falserecoveryLastValidValue:0pcount:0forjnpcountp{recoveryCurrent:seq[j]recoveryIsNormal:check(recoveryCurrent,recoveryHasLastValid,recoveryLastValidValue)ifrecoveryIsNormal{pcountrecoveryHasLastValidtruerecoveryLastValidValuerecoveryCurrent}else{pcount0recoveryHasLastValidfalserecoveryLastValidValue0}j}// 故障期间丢弃currentLen0errorWindow.Init()hasLastValidfalselastValidValue0ij-1}}i}fmt.Println(maxLen)}