禁止在 int 乘 int 时不开 long long
lzj20110120 · · 题解
十年OI一场空 不开 long long 见祖宗
所以这样的题目有什么实际意义?直接养成习惯开long long不就行了
废话不多说,我们进入正题。
题面传送门
题意简述
题目要求输入两个整数的范围,输出该范围内的数的乘积是否需要用 long long int 定义,如不需要则输出 int 。
一开始,本蒟蒻首先想到的居然是枚举,即将输入范围内的数枚举一遍,一个个的判断是否需要用 long long int 定义,也是十分荣幸地收获了一片青WA叫。
还是附上错误代码:
P1401 1.0版本
#include <bits/stdc++.h>
using namespace std;
long long a,b,x,y;
int main()
{
cin>>a>>b>>x>>y;
for(int i=a;i<=b;i++)
{
for(int j=x;j<=y;j++)
{
if(abs(i*j)>2147483647)
{
cout<<"long long int"<<endl;
return 0;
}
}
}
cout<<"int"<<endl;
return 0;
}
该代码的错误原因则是因为超过了运算范围。
此刻 1LL 就显现出它的作用了。
也许大多数人还不知道这个东西的存在,它的作用是:
“会在运算时把后面的临时数据扩容成long long类型,再在赋值给左边时转回int类型。”
以上内容转载自1LL随手记
所以,将其加入到代码当中,便有了
P1401 1.5版本
#include <bits/stdc++.h>
using namespace std;
long long a,b,x,y;
int main()
{
cin>>a>>b>>x>>y;
for(int i=a;i<=b;i++)
{
for(int j=x;j<=y;j++)
{
if(abs(1LL*i*j)>2147483647)
{
cout<<"long long int"<<endl;
return 0;
}
}
}
cout<<"int"<<endl;
return 0;
}
喜提五彩斑斓的黑。
这说明什么?说明枚举在本题中根本不可行!
那么我们抛弃枚举,直接通过判断极值的方法来求解,也就是直接判断该范围内最大和最小的数。
为何要判断最小的呢?别忘了 int 也是有最小值 −2147483648 ,所以判断最小值也是很必要的。
同样的,别忘了1LL!1LL!1LL!(重要的事情说3遍)
P1401 2.0版本
#include <bits/stdc++.h>
using namespace std;
long long a,b,x,y;
int main()
{
cin>>a>>b>>x>>y;
if(1LL*b*x>2147483647||1LL*b*x<-2147483648||1LL*a*y>2147483647||1LL*a*y<-2147483648||1LL*a*x>2147483647||1LL*a*x<-2147483648||1LL*b*y>2147483647||1LL*b*y<-2147483648)
{
cout<<"long long int"<<endl;
}
else
{
cout<<"int"<<endl;
}
return 0;
}
最后的最后,AC记录