当前位置: 首页 > news >正文

UVa 250 Pattern Matching Prelims

题目分析

本题属于光学字符识别(OCR\texttt{OCR}OCR)中的预处理问题。在字符识别过程中,扫描得到的图像往往存在噪声、形变,导致字符的大小、位置和方向发生变化。为了能够将扫描图像与标准模板进行匹配,需要找到图像中的一个基准点——重心Center of Gravity\texttt{Center of Gravity}Center of Gravity),作为对齐的参考点。

重心的定义

对于一个n×mn \times mn×m的灰度矩阵,每个元素的值在[0,1][0,1][0,1]之间,000表示白色,111表示黑色。重心的位置由行和列分别独立确定:

  • 行的选择:假设重心在第iii行,那么忽略第iii行后,上方所有行的元素之和与下方所有行的元素之和的差值应尽可能小。
  • 列的选择:类似地,忽略第jjj列后,左侧所有列的元素之和与右侧所有列的元素之和的差值应尽可能小。

特别地,如果存在多个满足最小差值的行或列,则选择行号最大、列号最大的那一组。

输入输出格式

  • 输入由多组数据组成,每组数据第一行为两个整数RRRCCC,分别表示矩阵的行数和列数,满足1≤R,C≤251 \leq R, C \leq 251R,C25。接下来是R×CR \times CR×C个浮点数,按照行主序给出。输入以0 0结束。
  • 输出格式:对于每组数据,输出Case k: center at (r, c),其中kkk111开始编号。

样例分析

以题目中的5×55 \times 55×5矩阵为例:

0.7 0.75 0.7 0.75 0.8 0.55 0.3 0.2 0.1 0.7 0.8 0.1 0.0 0.0 0.8 0.7 0.0 0.0 0.0 0.8 0.8 0.9 0.8 0.75 0.9

计算各行元素之和:

  • 111行:3.73.73.7
  • 222行:1.851.851.85
  • 333行:1.71.71.7
  • 444行:1.51.51.5
  • 555行:4.154.154.15

总行和:12.912.912.9

对于行i=3i=3i=3(忽略第333行),上方行和 =3.7+1.85=5.553.7 + 1.85 = 5.553.7+1.85=5.55,下方行和 =1.5+4.15=5.651.5 + 4.15 = 5.651.5+4.15=5.65,差值为0.10.10.1。因此重心在第333行。

类似地,计算各列之和,可得重心在第333列。

解题思路

初步思考

最直接的方法是:对于每一行iii,分别计算上方元素和与下方元素和,然后求差值,找到最小差值对应的行。列也类似。时间复杂度为O(R×C×(R+C))O(R \times C \times (R + C))O(R×C×(R+C))。由于R,C≤25R, C \leq 25R,C25,这个复杂度完全可行(约25×25×50=3125025 \times 25 \times 50 = 3125025×25×50=31250次操作)。

但我们可以进一步优化。

前缀和优化

注意到“忽略第iii行”后,上方元素和就是第111行到第i−1i-1i1行的元素之和,下方元素和就是第i+1i+1i+1行到第RRR行的元素之和。因此,如果我们预先计算出每一行的元素和(即行前缀和),就可以在O(1)O(1)O(1)时间内得到任意分割的上下方元素和。

设:

  • rowSum[i]rowSum[i]rowSum[i]表示原矩阵第iii行的元素之和(1≤i≤R1 \leq i \leq R1iR)。
  • prefixRow[i]=∑k=1irowSum[k]prefixRow[i] = \sum_{k=1}^{i} rowSum[k]prefixRow[i]=k=1irowSum[k]表示前iii行的元素和。

那么:

  • 忽略第iii行后,上方元素和 =prefixRow[i−1]prefixRow[i-1]prefixRow[i1]
  • 下方元素和 =totalSum−prefixRow[i]totalSum - prefixRow[i]totalSumprefixRow[i],其中totalSum=prefixRow[R]totalSum = prefixRow[R]totalSum=prefixRow[R]

差值 =∣prefixRow[i−1]−(totalSum−prefixRow[i])∣=∣totalSum−prefixRow[i]−prefixRow[i−1]∣\big| prefixRow[i-1] - (totalSum - prefixRow[i]) \big| = \big| totalSum - prefixRow[i] - prefixRow[i-1] \big|prefixRow[i1](totalSumprefixRow[i])=totalSumprefixRow[i]prefixRow[i1]

同理,对于列:

  • colSum[j]colSum[j]colSum[j]表示原矩阵第jjj列的元素之和。
  • prefixCol[j]=∑k=1jcolSum[k]prefixCol[j] = \sum_{k=1}^{j} colSum[k]prefixCol[j]=k=1jcolSum[k]
  • 忽略第jjj列后,左侧元素和 =prefixCol[j−1]prefixCol[j-1]prefixCol[j1],右侧元素和 =totalSum−prefixCol[j]totalSum - prefixCol[j]totalSumprefixCol[j]
  • 差值 =∣totalSum−prefixCol[j]−prefixCol[j−1]∣\big| totalSum - prefixCol[j] - prefixCol[j-1] \big|totalSumprefixCol[j]prefixCol[j1]

处理多个最优解

题目要求:如果有多行能使差值最小,选择行号最大的;列同理。因此我们在遍历行和列时,应该从大到小遍历,并仅在遇到更小的差值时才更新答案,这样最后一个遇到的“相等”差值就不会覆盖之前更大的行号。

边界情况

  • R=1R=1R=1时,没有“上方”和“下方”行,此时忽略唯一的一行后,上下方和均为000,差值为000,重心行取111
  • C=1C=1C=1时类似。

在代码实现中,我们从R−2R-2R2开始下降到111,并将初始的最小行设为R−1R-1R1(最后一行的上一行),初始差值设为∣totalSum∣\big|totalSum\big|totalSum。这样可以正确处理边界。

浮点数精度

由于输入是浮点数,直接比较相等可能因精度问题出错。因此我们使用一个小的容差值EPSILON = 1E-6,在比较temp<minDifferencetemp < minDifferencetemp<minDifference时,使用temp + EPSILON < minDifference来避免浮点误差。

代码实现

// Pattern Matching Prelims// UVa ID: 250// Verdict: Accepted// Submission Date: 2016-05-23// UVa Run Time: 0.040s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constdoubleEPSILON=1E-6;// 浮点数比较的容差值intmain(){cin.tie(0);// 加速输入输出cout.sync_with_stdio(false);vector<double>sumOfRows,sumOfColumns;// 存储行和列的前缀和introw,column,cases=0;while(cin>>row>>column,row&&column)// 读取矩阵大小,遇到0 0结束{sumOfRows.clear();sumOfColumns.clear();sumOfRows.resize(row);// 调整行前缀和数组大小sumOfColumns.resize(column);// 调整列前缀和数组大小fill(sumOfRows.begin(),sumOfRows.end(),0.0);fill(sumOfColumns.begin(),sumOfColumns.end(),0.0);doublevalue;// 读取矩阵元素,同时累加每一行和每一列的和for(inti=0;i<row;i++)for(intj=0;j<column;j++){cin>>value;sumOfRows[i]+=value;// 累加到对应行sumOfColumns[j]+=value;// 累加到对应列}// 计算行前缀和:sumOfRows[i] 现在表示前 i+1 行的元素和for(inti=1;i<sumOfRows.size();i++)sumOfRows[i]+=sumOfRows[i-1];// 计算列前缀和:sumOfColumns[j] 现在表示前 j+1 列的元素和for(intj=1;j<sumOfColumns.size();j++)sumOfColumns[j]+=sumOfColumns[j-1];doubletotal=sumOfRows[row-1];// 矩阵所有元素的总和// 寻找最优行:从最后一行向前遍历,保证遇到相等差值时保留更大的行号intminRow=row-1;doubleminDifference=fabs(total);// 初始差值:忽略第一行时的情况// i 从 row-2 到 1,对应实际行号从 row-1 到 2(因为需要上下都有行)for(inti=row-2;i>=1;i--){// 忽略第 i+1 行(0-indexed)时的差值doubletemp=fabs(total-sumOfRows[i]-sumOfRows[i-1]);// 如果找到更小的差值,更新答案if(temp+EPSILON<minDifference){minRow=i;minDifference=temp;}}// 寻找最优列:从最后一列向前遍历intminColumn=column-1;minDifference=fabs(total);// 初始差值:忽略第一列时的情况for(intj=column-2;j>=1;j--){doubletemp=fabs(total-sumOfColumns[j]-sumOfColumns[j-1]);if(temp+EPSILON<minDifference){minColumn=j;minDifference=temp;}}// 将 0-indexed 转换为 1-indexed 输出minRow++;minColumn++;cout<<"Case "<<++cases;cout<<": center at ("<<minRow<<", "<<minColumn<<")"<<endl;}return0;}

复杂度分析

  • 时间复杂度O(R×C)O(R \times C)O(R×C),主要来自输入读取和前缀和计算,遍历行和列各需O(R+C)O(R + C)O(R+C)
  • 空间复杂度O(R+C)O(R + C)O(R+C),用于存储行和列的前缀和。

总结

本题的核心是利用前缀和技巧将原本需要O(R×C)O(R \times C)O(R×C)的区间和查询优化为O(1)O(1)O(1),从而快速计算忽略某行或某列后的上下/左右元素和。同时需要注意浮点精度处理和多个最优解时的选择规则。

http://www.jsqmd.com/news/861238/

相关文章:

  • 【编号938】东南沿海诸河流域边界+东南沿海诸河流域水系矢量多级水系
  • 边缘AI框架:在边缘设备上运行AI模型
  • cursor-vip:当AI编程工具遇上共享经济,你的代码从此有了智能伙伴
  • 16. 编译与构建工具
  • 2026电镀镍标牌技术全解析:镍标牌厂家/镍标牌定制/镍转印标/不锈钢标牌/家电标牌/枪瞄标牌/电动车标牌/电铸镍标牌/选择指南 - 优质品牌商家
  • Python微服务架构:从单体到分布式的演进
  • UVa 253 Cube Painting
  • 小数据下防止过拟合的四大策略,深度学习模型训练与开发
  • 带标注的螺丝、螺栓、垫圈缺陷识别数据集,包含缺陷里包含生锈和划痕,1291张图,支持yolo,coco json,voc xml,文末有模型训练代码。
  • 2026年5月新发布:量化评估天津别墅装修源头公司,诺亚方舟装饰集团实力解析 - 2026年企业推荐榜
  • VS Code 响应式网站手机界面预览全【简易】指南
  • 2026年空压机出租报价核心维度拆解与实操参考:空压机出租报价/进口空压机出租/长臂锚固钻机出租/低噪音空压机出租/选择指南 - 优质品牌商家
  • Python事件驱动架构:设计模式与实战
  • 受够了网盘限速?2026年更顺手的不限速同步盘选择
  • 超宽自锚式悬索桥模型修正与抗震可靠度分析【附仿真】
  • 2026年山地车定制厂家综合:途锐达凭何成为口碑之选? - 2026年企业推荐榜
  • 2026年4月超纯水设备企业推荐,10吨双级高纯水设备/高纯水设备/超纯水设备/软化水设备,超纯水设备采购渠道怎么选择 - 品牌推荐师
  • 图解人工智能(31)深度学习前沿
  • Python API网关:架构设计与实战
  • 国内靠谱5吨软化水设备怎么选?认准诚信老牌厂家不踩坑,中水回用设备/5吨软化水设备,软化水设备品牌哪家可靠 - 品牌推荐师
  • GanttProject终极指南:免费开源的项目管理工具完全攻略
  • 建筑数据驱动预测控制方法【附模型】
  • 2026年AI面试助手深度测评:鹅来面 OfferGoose如何革新你的求职体验?
  • 2026会议复印机租赁标杆名录:公司复印机租赁/办公室打印机租赁/单位复印机租赁/单位打印机租赁/品牌复印机租赁/选择指南 - 优质品牌商家
  • 图解人工智能(32)深度学习前沿
  • SMA驱动的空间杆系结构地震响应控制模型试验与理论分析【附代码】
  • 2025-2026年国内天津国际高中推荐:五大排行专业评测解决择校迷茫痛点 - 品牌推荐
  • Python缓存策略:从理论到实践
  • 2026企业网盘选型对比:坚果云领衔,5款主流产品优劣与场景建议
  • 如何在5分钟内掌握DistroAV网络视频传输:新手完整指南