Codechef Long Challenge题:1~N最长按位与为正子数组代码错误排查
问题描述
给定整数N,考虑严格递增序列1,2,…,N(每个数恰好出现一次),求该序列中所有元素的bitwise AND(按位与)结果为正的最长子数组的长度。
代码存在的问题
- 浮点运算精度问题:代码依赖
pow浮点函数计算2的幂次,double类型仅能精确表示2^53以内的整数,超过该范围的整数会出现精度损失,导致最高位幂次i计算错误,后续逻辑全部失效。同时临界值附近的浮点误差(如pow(2,10)返回1023.9999999999)也会导致判断逻辑出错。 - 输出格式错误:输出时直接打印
pow返回的浮点值,当数值较大时会默认以科学计数法格式输出,不符合算法题要求的整数输出格式,OJ会直接判错。 - 边界鲁棒性不足:代码未处理
i=0的边界场景,虽然n=1时当前逻辑刚好输出正确结果,但如果入参允许n=0,会出现负指数计算错误,逻辑存在隐患。
失效测试用例
- 测试用例1:输入
n=1073741824(即2^30),预期输出536870912。代码中pow(2,30)/2返回浮点值536870912.0,部分编译器会输出为5.36871e+08,格式不符合要求被判错。 - 测试用例2:输入
n=9007199254740993(即2^53+1,超出double精确整数范围),pow无法精确计算该量级的2的幂次,导致最高位i计算错误,输出结果完全不符合预期。
修正方案
将所有pow浮点运算替换为整数位运算,避免精度问题,同时统一用整数类型计算和输出结果,修正后的代码如下:
#include <iostream> #include <algorithm> using namespace std; int main() { int t; long long n; cin >> t; while (t--) { cin >> n; int k = 0; // 位运算求小于等于n的最大2的幂次的指数k while ((1LL << (k + 1)) <= n) { k++; } long long len_high = n - (1LL << k) + 1; long long len_low = (k >= 1) ? (1LL << (k - 1)) : 1; cout << max(len_high, len_low) << endl; } return 0; }
内容的提问来源于stack exchange,提问作者Tanishk Agarwal
相关产品推荐
相关产品推荐

