【整数溢出】为什么把j*j<=p改成j<=sqrt(q)就解决了超时的问题

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;cin>>n;int p;
	for(int i=0;i<n;i++){
		cin>>p;
		if(p<2)cout<<"No\n";
		else if(p==2)cout<<"Yes\n";
		else{
			int flag=0;
			for(int j=2;j*j<=p;j++){
				if(p%j==0){cout<<"No\n";flag=1;break;}
			}
			if(flag==0)cout<<"Yes\n";
		}
	}
	return 0;
}

这个代码一直有一个超时。

但是把j*j<=p改成j<=sqrt(q)就过了。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;cin>>n;int p;
	for(int i=0;i<n;i++){
		cin>>p;
		if(p<2)cout<<"No\n";
		else if(p==2)cout<<"Yes\n";
		else{
			int flag=0;
			for(int j=2;j<=sqrt(p);j++){
				if(p%j==0){cout<<"No\n";flag=1;break;}
			}
			if(flag==0)cout<<"Yes\n";
		}
	}
	return 0;
}

问了下AI,AI告诉我是这个原因:

j*j 发生整数溢出

你的代码里:

cpp 复制代码
int p; for(int j=2; j*j<=p; j++)

如果 p 的范围比较大(例如接近 2e9),

j > 46340 时:

cpp 复制代码
46341 * 46341 > INT_MAX

j*j 会超出 int 范围,产生 有符号整数溢出(未定义行为)。

溢出后:

  • j*j 可能变成负数

  • 条件 j*j <= p 可能一直成立

  • 循环不会按 √p 停止

  • 可能跑到非常大 → 超时

果然我改成

cpp 复制代码
for(long long j=2;j*j<=p;j++)

就可以了。

毕竟这道题上界是,很有必要考虑一下整数溢出的问题。

相关推荐
Sapphire小蓝2 年前
L1-101 别再来这么多猫娘了!(string类关键函数解决)
c++·string·天梯赛
是基德吖2 年前
L2-045 堆宝塔
c++·stl··stack·天梯赛
是基德吖2 年前
L2-042 老板的作息表
sort·结构体·字典序·天梯赛·结构体排序
乱码怪才2 年前
L1-093:猜帽子游戏
c语言·算法·天梯赛
乱码怪才2 年前
L1-091:程序员买包子
c语言·算法·天梯赛
乱码怪才2 年前
L1-078:吉老师的回归
c语言·算法·天梯赛
乱码怪才2 年前
L1-072:刮刮彩票
c语言·算法·天梯赛
乱码怪才2 年前
L1-060:心理阴影面积
c语言·算法·天梯赛
乱码怪才2 年前
L1-041:寻找250
c语言·算法·天梯赛