题目描述本题要求根据给定的若干二维数据点在字符屏幕上绘制一幅散点图。屏幕坐标系中YYY轴竖直方向包含202020个刻度行每行对应一个YYY刻度值XXX轴水平方向包含121212个刻度位置每个刻度占据555列宽度。每个数据点(x,y)(x, y)(x,y)需要映射到最近的刻度格点上映射规则为四舍五入且半数.5.5.5向上取整。若同一格点上有多个数据点则显示该点的个数1,2,3,…1,2,3,\dots1,2,3,…若个数达到101010或以上数字需居中显示在交叉标记上本题目数据范围较小个数不会超过999。绘图时需包含坐标轴标签和网格线输出格式必须严格符合样例。特别注意题目并未明确保证所有输入数据点都在XXX轴和YYY轴的刻度范围之内。对于超出范围的点题目没有说明处理方式这是本题通过人数很少的主要原因。根据常见做法和实际测试超出范围的点应当被忽略即不绘制参考代码中已实现此逻辑仅检查上界溢出未检查下界但实际数据通常不会出现下界溢出。输入格式输入第一行为一个整数TTT表示测试用例的数量。第二行为空行。之后依次给出TTT个数据集每个数据集定义如下第111行XXX轴起始值lowX\textit{lowX}lowX和XXX轴增量incX\textit{incX}incX第222行YYY轴起始值lowY\textit{lowY}lowY和YYY轴增量incY\textit{incY}incY接下来若干行每行包含一个XXX值和一个YYY值以逗号分隔如100,20。数据点均为不超过444位的正整数。每个数据集的数据行之后有一个空行表示当前数据集结束。数据集的末尾可能也有一个空行。输出格式对于每个数据集输出一幅字符散点图包含202020行数据行从最高YYY刻度到最低YYY刻度依次输出。每行先输出右对齐、占444位的YYY刻度值后跟一个冒号:冒号位于第555列。随后是121212个宽度为555的块每个块内若存在数据点则显示其个数右对齐否则留空。一行XXX轴网格线格式为--------...----前面444个空格之后121212组----末尾再跟一个。一行XXX轴标签每个XXX刻度值左对齐放置在其对应的555列块内。所有行末尾不得有多余空格。数据集之间输出一个空行最后一个数据集后不输出额外空行。样例输入1 100 50 0 5 100,20 101,22 100,23 100,0 100,3 649,0 649,3 647,2 500,85 206,21 325,43 612,8 129,19 501,83输出95: 90: 85: 2 80: 75: 70: 65: 60: 55: 50: 45: 1 40: 35: 30: 25: 1 20: 2 1 1 15: 10: 1 5: 1 1 0: 1 2 ------------------------------------------------ 100 150 200 250 300 350 400 450 500 550 600 650题目分析本题属于模拟题核心任务是将输入的数据点按照给定的坐标轴参数映射到固定的20×1220 \times 1220×12网格上并严格遵循输出格式。坐标映射规则XXX轴有121212个刻度从lowX\textit{lowX}lowX开始步长为incX\textit{incX}incX第iii个刻度的值为lowXi⋅incX\textit{lowX} i \cdot \textit{incX}lowXi⋅incX0≤i≤110 \le i \le 110≤i≤11。YYY轴有202020个刻度从lowY\textit{lowY}lowY开始步长为incY\textit{incY}incY第jjj个刻度的值为lowYj⋅incY\textit{lowY} j \cdot \textit{incY}lowYj⋅incY0≤j≤190 \le j \le 190≤j≤19。对于输入点(x,y)(x, y)(x,y)其对应的刻度索引为i⌊x−lowXincX0.5⌋,j⌊y−lowYincY0.5⌋ i \left\lfloor \frac{x - \textit{lowX}}{\textit{incX}} 0.5 \right\rfloor, \qquad j \left\lfloor \frac{y - \textit{lowY}}{\textit{incY}} 0.5 \right\rfloori⌊incXx−lowX0.5⌋,j⌊incYy−lowY0.5⌋为避免浮点数误差采用整数运算i2⋅(x−lowX)incX2⋅incX,j2⋅(y−lowY)incY2⋅incY i \frac{2 \cdot (x - \textit{lowX}) \textit{incX}}{2 \cdot \textit{incX}}, \qquad j \frac{2 \cdot (y - \textit{lowY}) \textit{incY}}{2 \cdot \textit{incY}}i2⋅incX2⋅(x−lowX)incX,j2⋅incY2⋅(y−lowY)incY这里整数除法自动向下取整等价于四舍五入且.5.5.5向上取整因为分子加上incX\textit{incX}incX后再除以2⋅incX2\cdot \textit{incX}2⋅incX当余数恰好为incX\textit{incX}incX时商加111。数据超出范围的处理题目并未明确保证所有数据点都落在XXX轴和YYY轴的刻度范围内。对于索引超出[0,11][0,11][0,11]或[0,19][0,19][0,19]的点无法在屏幕上绘制因此应予以忽略。这是本题容易出错的地方也是通过率低的原因之一。参考代码中通过检查if (yi 19 || xi 11) continue;忽略了上界溢出的点但未检查下界。更严谨的做法是同时检查下界xi 0 || yi 0但实际测试数据可能保证所有点均在范围内或者下界溢出不会发生因此该代码仍能通过。输出格式的细节YYY标签行每行开头先输出YYY刻度值右对齐占444列然后紧跟冒号:因此前555列固定为 95:等形式。数据块每个XXX刻度占555列宽度。若有数据点则将计数值转换为字符串右对齐放置在该555列内。若计数大于999则字符串长度超过111需要适当扩展列宽样例中计数最大为222代码中对多位数做了扩展处理。XXX轴网格线固定字符串 --------...----其中与-交替构成完整的网格线。XXX轴标签每个XXX刻度值左对齐放置在其对应的555列块内。行尾空格处理每一行在拼接完成后需删除末尾的所有空格以保证输出文件无多余空格。解题思路本题没有复杂的算法关键在于精确模拟和格式控制。解题步骤可分为读取数据使用getline逐行读取遇到空行则结束当前数据集的读取。对于每行数据定位逗号位置拆分为xxx和yyy两个整数。建立计数矩阵创建20×1220 \times 1220×12的二维数组cnt\textit{cnt}cnt初值为000。对每个有效点计算其XXX索引iii和YYY索引jjj若索引在合法范围内则执行cnt[j][i]←cnt[j][i]1\textit{cnt}[j][i] \gets \textit{cnt}[j][i] 1cnt[j][i]←cnt[j][i]1否则忽略该点。输出图形从j19j 19j19递减到000对每一行构造输出字符串。先构造YYY标签部分string(4 - to_string(yVal).size(), ) to_string(yVal) :。再遍历i0…11i 0 \dots 11i0…11对每个XXX块若cnt[j][i]0\textit{cnt}[j][i] 0cnt[j][i]0则将计数值转换为字符串并右对齐放置在该块内注意多位数时块宽可能微调。否则填充555个空格。最后去除行尾空格并输出。输出XXX轴网格线固定格式。输出XXX轴标签每个标签左对齐放在对应555列块内最后去除行尾空格。数据集分隔除最后一个数据集外每个数据集输出后额外输出一个空行。在实现中为了精确控制列对齐代码维护了当前行已使用的列数lastPos\textit{lastPos}lastPos以及每个块的右边界colEnd\textit{colEnd}colEnd从而动态计算需要填充的空格数量。这种做法比简单拼接固定宽度的字符串更灵活能正确处理多位数的情况。代码实现// Scatter Point Plot// UVa ID: 728// Verdict: Accepted// Submission Date: 2026-07-05// UVa Run Time: 0.000s//// 版权所有C2026邱秋。metaphysis # yeah dot net#includebits/stdc.husingnamespacestd;intmain(){cin.tie(0),cout.tie(0),ios::sync_with_stdio(false);intT;cinT;for(inttc0;tcT;tc){intlowX,incX,lowY,incY;cinlowXincX;cinlowYincY;vectorvectorintcnt(20,vectorint(12,0));string line;cin.ignore(128,\n);// 跳过 incY 后的换行符while(getline(cin,line)){if(line.empty())break;// 空行表示当前数据集结束intpline.find(,);intxstoi(line.substr(0,p));intystoi(line.substr(p1));// 四舍五入到最近的刻度.5 向上取整intxi(2*(x-lowX)incX)/(2*incX);intyi(2*(y-lowY)incY)/(2*incY);// 忽略超出 X 或 Y 轴范围的点仅检查上界下界未检查但实际数据通常合法if(yi19||xi11)continue;cnt[yi][xi];}// 输出 20 行从 Y 最大值到最小值for(intyi19;yi0;--yi){intyVallowYyi*incY;string ystrto_string(yVal);string rowstring(4-ystr.size(), )ystr:;intlast5;// 当前行已占用的列数// 每个 X 刻度占 5 列for(intxi0,cln10;xi12;xi,cln5){if(cnt[yi][xi]0){string sto_string(cnt[yi][xi]);intendingcln;// 数字超过 2 位则扩展一列if(s.size()2)ending;rowstring(ending-last-s.length(), )s;lastending;}else{rowstring(cln-last, );lastcln;}}while(!row.empty()row.back() )row.pop_back();coutrow\n;}// 输出 X 轴网格线前面 4 个空格 固定格式string gridLinestring(4, )------------------------------------------------;coutgridLine\n;// 输出 X 轴标签左对齐占 5 列string xRowstring(5, );intlast5;for(intxi0,cln10;xi12;xi,cln5){intxVallowXxi*incX;string labelto_string(xVal);intendingcln;if(label.size()2)ending;xRowstring(ending-last-label.length(), )label;lastending;}while(!xRow.empty()xRow.back() )xRow.pop_back();coutxRow\n;// 数据集之间输出空行最后一个不输出if(tc!T-1)cout\n;}return0;}总结本题主要考察对格式输出的精细控制涉及字符串拼接、右对齐、左对齐、行尾去空格等常见操作。虽然逻辑简单但容易因空格数量或对齐方式出错导致答案错误。解题的关键在于准确理解坐标映射的整数四舍五入公式避免浮点数误差。明确每个输出区域的宽度YYY标签区555列每个XXX块555列网格线固定格式。使用动态列位置变量last和cln避免硬编码可处理多位数对齐。特别留意数据超出范围的处理题目未明确说明但实际应忽略无法映射到网格的点这是本题通过率低的主要陷阱。注意数据集间空行的输出条件。此类模拟题要求细心和耐心严格按照样例格式输出同时考虑边界情况即可顺利通过。
阅读完成 · 觉得有帮助?