问题描述
格式输入
输入一行包含两个整数 L, R,用一个空格分隔。
格式输出
输出一行包含一个整数满足题目给定条件的 x 的数量。
样例输入
1 5
样例输出
4
评测用例规模与约定
对于 40% 的评测用例,L R ≤ 5000 ;
对于所有评测用例,1 ≤ L ≤ R ≤ 10^9 。
解析
暴力没说的,y肯定在l-r之间。同时要想到x=(y+z)(y-z)那么x就只能是y+z的倍数。 啊啊啊,感谢提醒,有可能一个数还有不同的组合。
1.使用了两层循环,分别用于枚举 y 和 z。对于每一个 y 和 z,都可以根据题目给定的公式
x
=
y
2
−
z
2
x=y^2-z^2
x=y2−z2 计算出对应的 x 值。如果 x 值在区间 [L, R] 中,那么就将答案加一。最后输出答案即可。
需要注意的是,由于输入范围很大,因此对应的数据类型也需要选择比较大的类型,这里使用了 long long 类型。
参考程序
~~#include
#include
using namespace std;
typedef long long LL; // 定义 long long 类型为 LL
int main()
{
LL L, R;
cin >> L >> R;
int ans = 0;
for (LL i = 1; i <= R; i++) { // 遍历所有的 y
for (LL j = 0; j <= i; j++) { // 遍历所有的 z
LL x = i * i - j * j; // 根据公式计算出 x
if (x >= L&&x<=R) ans++; // 如果 x 在区间 [L, R] 中,累加答案
}
}
cout << ans << endl; // 输出答案
return 0;
}
~~ 改后 过40% 肯定是超时了,第一个点可以过,大佬们看看怎么不会超时。
#include<iostream>
using namespace std;
#include<vector>
typedef long long ll;
ll a[100000010];
int main()
{
ll l, r;
cin >> l >> r;
int ans = 0;
for (ll i = 1; i <= r; i++) { // 遍历所有的 y
for (ll j = 0; j <= i; j++) { // 遍历所有的 z
ll x = i * i - j * j; // 根据公式计算出 x
if(x>=l&&x<=r) a[x]++;//x的出现存到数组里
}
}
for (long long i = 1; i <= r; i++)
{
if (a[i] > 0) ans++;
}
cout << ans << endl; // 输出答案
return 0;
}
补的在大佬们点拨下:一些数论的知识,算出不能表示的数(不能被4整除可以被2整除)的个数减去。O(1)复杂度。文章来源:https://www.toymoban.com/news/detail-413570.html
#include <iostream>
using namespace std;
int main() {
int L, R;
cin >> L >> R;
int cnt = (R / 2) - ((L - 1) / 2) - (R / 4) + ((L - 1) / 4);
cout << R-L+1-cnt<< endl;
return 0;
}
以个人刷题整理为目的,如若侵权,请联系删除~文章来源地址https://www.toymoban.com/news/detail-413570.html
到了这里,关于第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 A 组 C题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!