Codesignal矩形旋转问题:求分析我的解法错误原因
分析斜矩形内整数点计数代码的错误原因
问题描述
在笛卡尔平面上绘制一个边长为偶数整数a和b的矩形,其中心(对角线交点)与原点(0,0)重合,矩形的边不与坐标轴平行,而是与坐标轴成45度角。需要计算位于该矩形内部(包括边上)的整数坐标点数量。
参考解法代码
int solution(int a, int b) { a/=Math.sqrt(2); b/=Math.sqrt(2); return (2*a*b+a+b)|1; }
我的代码
int solution(int a, int b) { double k1 = b/Math.sqrt(2); double k2 = a/Math.sqrt(2); int ini = ((int)(Math.floor(min(k1, k2))))*2+1; int temp=ini; int num=0; while(temp>0){ num += temp*2; temp-=2; } return num+ini*((int)(Math.floor(Math.abs(k2-k1)/2))*2+1); } double min(double a, double b){ return a>b ? b:a; }
错误原因分析
1. 旋转矩形的点分布逻辑理解完全错误
旋转45度的矩形在原坐标系下的整数点分布,不能用“分层累加初始序列 + 倍数扩展”的方式计算。这种逻辑是基于轴对齐矩形的点分布想象出来的,完全不符合旋转后矩形的边界特征,导致计数结果严重偏离实际值。
2. 浮点数计算引入精度误差
直接使用Math.floor()对b/Math.sqrt(2)这类浮点数取整,会因为浮点数的精度限制导致错误。例如当a或b的值使得a/√2非常接近整数时,浮点数的舍入误差可能导致floor取整结果偏差1,进而影响后续所有计数步骤。
3. 计数逻辑重复/遗漏
代码中num += temp*2的循环累加,与后面ini*((int)(Math.floor(Math.abs(k2-k1)/2))*2+1)的叠加部分,既没有对应旋转矩形的实际区域,也没有考虑整数点的奇偶性约束(整数点(x,y)对应u=x+y和v=x−y必须同奇偶,才能保证x和y是整数),导致要么重复计数,要么遗漏大量符合条件的点。
4. 未利用坐标变换简化问题
正确的思路是通过坐标变换u=x+y、v=x−y,将旋转矩形转换为轴对齐矩形,再统计满足条件的整数对(u,v)中u和v同奇偶的数量。你的代码完全没有采用这种简化方法,而是在原坐标系下硬套错误的计数模型。
内容的提问来源于stack exchange,提问作者이동준
相关产品推荐
相关产品推荐

