intmain(){ cin >> n >> m; for (int i = 0; i < n; i++) { cin >> q[i]; } while (m--) { int x; cin >> x; int l = 0, r = n -1; while (l < r) { // 二分查找目标数的起始位置 int mid = l + r >> 1; if (q[mid] >= x) { r = mid; } else { l = mid + 1; } } if (q[l] == x) { // 如果查询到了起始位置 cout << l << ' '; // 输出下标 r = n - 1; // 定右边界,此时l为需要寻找的数的起始下标 while (l < r) { // 在该数的右边进行二分 int mid = l + r + 1 >> 1; if (q[mid] <= x) { l = mid; } else { r = mid - 1; } } cout << r << endl; } else { cout << "-1 -1" << endl; } } return0; }
boolcheck(int e){ for (int i = 1; i <= n; i++) { e = e * 2 - h[i]; if (e >= 1e5) { // 若n大于建筑高度的最大值 returntrue; } elseif (e < 0) { // 若能量为负 returnfalse; } } }
intmain(){ cin >> n; for (int i = 1; i <= n; i++) { cin >> h[i]; } int l = 0, r = 1e5; while (l < r) { int mid = l + r >> 1; if (check(mid)) { r = mid; } else { l = mid + 1; } } cout << r << endl; return0; }
4. 四平方和
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多 4 个正整数的平方和。
如果把 0 包括进去,就正好可以表示为 4 个数的平方和。
比如:
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对 4 个数排序:
0≤a≤b≤c≤d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。
输入格式
输入一个正整数 N。
输出格式
输出4个非负整数,按从小到大排序,中间用空格分开。
数据范围
输入样例:
1
5
输出样例:
1
0 0 1 2
AC
暴力解会超时,所以利用结构体来做哈希表,存放所有的枚举可能性
结构体存 c、d 两个数,直接二重循环枚举 a、b 两个数,然后二分判断结构体下标,即对应的 c 、d 的平方和与 n - a a - b b 是否相等,从而减少时间复杂度
structSum { int s, c, d; booloperator< (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];
intmain(){ cin >> 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 * a <= n; a++) { for (int b = a; a * a + b * b <= 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); return0; } } } return0; }
boolcheck(int mid){ int res = 0; for (int i = 0; i < n; i++) { res += (h[i] / mid) * (w[i] / mid); // 求第i块的巧克力的 if (res >= k) { returntrue; } } returnfalse; }
intmain(){ cin >> n >> k; for (int i = 0; i < n; i++) { cin >> h[i] >> w[i]; } int l = 1, r = 1e5; while (l < r) { int mid = l + r + 1 >> 1; if (check(mid)) { l = mid; } else { r = mid - 1; } } cout << r << endl; return0; }