二分
// 拉格朗日定理 - 四平方和定理
// 任何一个正整数都可以由 4个整数的平方和
// 同样一个正整数, 可能存在多种方案
// a, b, c, d 按照一个递增的顺序进行排序, 输出最小的
// N <= 5e6
// a,b,c,d 都是<=N^1/2 每个数 0<= x <= 2200 左右
// 所以最多枚举2个数, 2200^2 , 三个数就 2200^3 = 8e9 所以最多2个
// 1. 最多只能枚举两个数
// 2. 如果可以枚举三个数 d = (N-a^2-b*2-c^2)^1/2
// 3. 所以需要考虑使用空间来换取时间
// 4. 本来需要枚举三重循环
/*
for(a)
for(b)
for(c)
*/
/*
for(c)
for(d=c;c^2+d^2<=N;d++) 先把两重循环的结果存下来
然后把所有的c^2+d^2存起来
然后再枚举 a 和 b
for(a)
for(b=a;a^2+b^2<=n;b++)
{
int d = n-a^2-b^2;
if (check(d)) ok
else continue;
}
check(d) 的时候可以二分
*/
// todo 补充一个语法 [运算符重载]
// todo 语法: 返回值类型 operator op(参数);
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 25e5 + 10;
struct Sum
{
int s, c, d; // s表示c和d的平方
bool operator<(const Sum& t) const //返回较小的那个
{
if(s != t.s) return s < t.s;
if(c != t.c) return c < t.c;
return d < t.d;
}
} sum[N];
int n, m;
int main(void)
{
scanf("%d", &n);
for(int c = 0; c * c <= n; c++)
for(int d = c; c * c + d * d <= n; d++) sum[m++] = {c * c + d * d, c, d};
sort(sum, sum + m);
for(int a = 0; a <= n; a++)
for(int b = 0; b * b + a * a <= n; b++)
{
int t = n - a * a - b * b;
int l = 0, r = m - 1;
while(l < r)
{
int mid = l + r >> 1;
if(sum[mid].s >= t) //要找一个最小的 所以是>=
r = mid;
else
l = mid + 1;
}
if(sum[l].s == t)
{
printf("%d %d %d %d\n", a, b, sum[l].c, sum[l].d);
return 0;
}
}
return 0;
}
哈希表
#include <iostream>
#include <unordered_map>
using namespace std;
typedef pair<int, int> pii;
int n;
unordered_map<int, pii> S;
int main(void)
{
scanf("%d", &n);
for(int c = 0; c <= n; c++)
for(int d = c; d * d + c * c <= n; d++)
{
int t = c * c + d * d;
if(S.count(t) == 0) S[t] = {c, d};
}
for(int a = 0; a <= n; a++)
for(int b = 0; a * a + b * b <= n; b++)
{
int t = n - a * a - b * b;
if(S.count(t))
{
printf("%d %d %d %d", a, b, S[t].first, S[t].second);
return 0;
}
}
return 0;
}
问一下楼主 这个那个N怎么算的 为什么要25e5这么大
想问一下二分的方法 这样可以保证a<=b和c<=d 但是怎么保证b<=c呢 没看出来哪里限制了这个条件呀
如果没有b<=c的话,是得不到答案的这个由 int t = n - a * a - b * b;保证了,你可以打表看看数据
好的 谢谢
哈希超时了
哈希超时了
我真傻了,为啥二分能过哈希过不了啊
不是二分是o(nlog)哈希是o(1)吗?
直接用数组映射的哈希表不会超时,估计是stl的哈希表频繁插入超时了(涉及到频繁增容)
我个人觉得是判断stl哈希表是否包含t的过程效率低,因为要频繁调用count成员函数,我开了一个bool数组单独判断包含t也过了,考虑到t的数量不会太多,应该不是散列冲突的问题
大佬 为什么用哈希表会tle呀 哈希表时间复杂度应该是N^2
比用二分小吧
加强数据这个也过不了了,哈希查找O(1),二分查找O(logn),哈希最快,但是这个题二分比哈希快,可能是数据集的问题吧,我也不是很清楚
嗯嗯 谢谢大佬
大佬 第一个做法 sort 后面 那个 两个for
1. a<=n 2. b * b + a * a <=n 的 时间复杂度 是多少?
N^2*logN