#include using namespace std; const int N = 5e6 + 10; struct Node { int c, d, sum; bool operator<(const Node &t) const { //对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。 //因为这个第一个表示法,使得我们首先需要对sum进行升序排列,如果sum值一样,就需要对c进行升序排列.至于说d,其实无所谓了,因为本题中不可能存在 // sum一样,c也一样的场景,但也许有的题不行,需要写全排序办法 if (sum != t.sum) return sum < t.sum; if (c != t.c) return c < t.c; return d < t.d; } } f[N]; int n; int idx; int main() { cin >> n; //枚举c^2+d^2 for (int c = 0; c * c <= n; c++) for (int d = c; c * c + d * d <= n; d++) f[idx++] = {c, d, c * c + d * d}; //结构体排序 sort(f, f + idx); //枚举a^2+b^2 for (int a = 0; a * a <= n; a++) { for (int b = a; a * a + b * b <= n; b++) { int t = n - a * a - b * b; int p = lower_bound(f, f + idx, Node{0, 0, t}) - f; /* 结构体+lower_bound需要注意的事项: 一、结构体中二分查找,需要封装成无用项置0的结构体: (1) 把我们需要查找的数封装成一个结构体。然后才可以在结构体重进行查找。即使我们只需要针对某一维进行查找,也需要把整个结构体构造出来。 (2) 这里我只需要查找第一维,并且我对第一维进行了排序,只有有序数列才可以进行二分,然后在查找的时候,把其他维置零即可。但是必须要封装成一个结构体 二、最终的结果需要进行判断 (1)、可能找到,也可能找不到 (2)、因为lower_bound返回的是数组中第一个大于等于Node{0,0,t}的位置,有三种可能: 1. 命中,找到sum=t,现在p就是结果位置 2. 没有命中,返回的是sum>t的第一个位置,这不是我们想要的结果,需要判断一下这样的情况。 3. 没有命中,返回的是数组外边的一个空地,也是越界了也没有找到大于等于t的第一个位置,这不是我们想要的结果,需要判断一下这样的情况 */ if (p < idx && f[p].sum == t) { cout << a << ' ' << b << ' ' << f[p].c << ' ' << f[p].d << ' ' << endl; return 0; } } } return 0; }