1001
描述
- 给出四个三维坐标下的点, 判定是否为正方形.
分析
- 用向量的数量积来判定是否垂直, 再判断长度.
- 我是在纸上画出了A(3,2)=6 种情况然后暴力枚举判断是否为正方形. 组合数的意义表示在 2、3、4 三个点中有序选出两个点和 1 相邻.
- 我写了一百多行的代码, 看了看别人简洁的代码, 发现可以直接用STL的
next_permutation
来生成下一个排列, 把排列看做从左上角开始的顺时针 (或逆时针) 四个点的编号, 就可以少打很多暴力枚举.- 尤其是在点数更多时这个办法更有用.
- 计算几何的一些常用函数还是打成函数比较好, 可以降低代码复杂度.
代码
https://code.csdn.net/snippets/647464
#include <cstdio>
using namespace std;
typedef long long lli;
struct Vector {
lli x, y, z;
Vector(lli x=0, lli y=0, lli z=0) : x(x), y(y), z(z) {}
void init() {
scanf("%lld%lld%lld", &x, &y, &z);
}
};
Vector operator - (Vector A, Vector B) {
return Vector(A.x-B.x, A.y-B.y, A.z-B.z);
}
lli Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y + A.z*B.z; }
lli Length2(Vector A) { return Dot(A, A); }
int main() {
int T;
scanf("%d", &T);
Vector p1, p2, p3, p4;
Vector u1, u2, u3, u4;
Vector v1, v2, v3, v4;
for(int kase = 1; kase <= T; kase++) {
printf("Case #%d: ", kase);
p1.init(); p2.init(); p3.init(); p4.init();
u1 = p2-p1; v1 = p3-p1;
u2 = p1-p2; v2 = p4-p2;
u3 = p2-p4; v3 = p3-p4;
u4 = p1-p3; v4 = p4-p3;
if(Dot(u1, v1) == 0 && Dot(u2, v2) == 0 && Dot(u3, v3) == 0 && Dot(u4, v4) == 0) {
if(Length2(u1) == Length2(v1) && Length2(u2) == Length2(v2) && Length2(u3) == Length2(v3) && Length2(u4) == Length2(v4)) puts("Yes");
else puts("No");
continue;
}
u1 = p2-p1; v1 = p4-p1;
u2 = p1-p2; v2 = p3-p2;
u3 = p2-p3; v3 = p4-p3;
u4 = p1-p4; v4 = p3-p4;
if(Dot(u1, v1) == 0 && Dot(u2, v2) == 0 && Dot(u3, v3) == 0 && Dot(u4, v4) == 0) {
if(Length2(u1) == Length2(v1) && Length2(u2) == Length2(v2) && Length2(u3) == Length2(v3) && Length2(u4) == Length2(v4)) puts("Yes");
else puts("No");
continue;
}
u1 = p3-p1; v1 = p2-p1;
u2 = p1-p3; v2 = p4-p3;
u3 = p3-p4; v3 = p2-p4;
u4 = p1-p2; v4 = p4-p2;
if(Dot(u1, v1) == 0 && Dot(u2, v2) == 0 && Dot(u3, v3) == 0 && Dot(u4, v4) == 0) {
if(Length2(u1) == Length2(v1) && Length2(u2) == Length2(v2) && Length2(u3) == Length2(v3) && Length2(u4) == Length2(v4)) puts("Yes");
else puts("No");
continue;
}
u1 = p3-p1; v1 = p4-p1;
u2 = p1-p3; v2 = p2-p3;
u3 = p3-p2; v3 = p4-p2;
u4 = p1-p4; v4 = p2-p4;
if(Dot(u1, v1) == 0 && Dot(u2, v2) == 0 && Dot(u3, v3) == 0 && Dot(u4, v4) == 0) {
if(Length2(u1) == Length2(v1) && Length2(u2) == Length2(v2) && Length2(u3) == Length2(v3) && Length2(u4) == Length2(v4)) puts("Yes");
else puts("No");
continue;
}
u1 = p4-p1; v1 = p2-p1;
u2 = p1-p4; v2 = p3-p4;
u3 = p4-p3; v3 = p2-p3;
u4 = p1-p2; v2 = p3-p2;
if(Dot(u1, v1) == 0 && Dot(u2, v2) == 0 && Dot(u3, v3) == 0 && Dot(u4, v4) == 0) {
if(Length2(u1) == Length2(v1) && Length2(u2) == Length2(v2) && Length2(u3) == Length2(v3) && Length2(u4) == Length2(v4)) puts("Yes");
else puts("No");
continue;
}
u1 = p4-p1; v1 = p3-p1;
u2 = p1-p4; v2 = p2-p4;
u3 = p3-p2; v3 = p4-p2;
u4 = p1-p3; v2 = p2-p3;
if(Dot(u1, v1) == 0 && Dot(u2, v2) == 0 && Dot(u3, v3) == 0 && Dot(u4, v4) == 0) {
if(Length2(u1) == Length2(v1) && Length2(u2) == Length2(v2) && Length2(u3) == Length2(v3) && Length2(u4) == Length2(v4)) puts("Yes");
else puts("No");
continue;
}
puts("No");
}
return 0;
}
1002
描述
- 在数组 a中找出两个数 ai, aj (i≠j), 使得 gcd(ai,aj) 取到最大值.
- 数组元素个数 n≤50000
分析
- 因为数组是给出的, 有不确定性, 所以放弃了找规律.
- 暴力拆解因数, 用 hash 表来存储这个因数有没有出现过. 如果这个因数出现过就更新答案, 否则标记为已出现.
- 枚举因数肯定是 [1,n√] 之内的, 同时如果 i 是 x 的因数, xi 也是 x 的因数, 如果 xi 出现过, 那么就可以不再继续枚举了. 因为随着 i 的增大, xi 会减小, 不会比现在答案更优.
- O(nn√)
- 还可以加一个优化, 就是把 a 数组 sort 后从大往小来判定. 这样提前搜到答案的几率或许更大一些.
代码
https://code.csdn.net/snippets/647465
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000 + 10;
bool factor[maxn];
int c[maxn];
int main() {
int T;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++) {
int n, ans = 1;
scanf("%d", &n);
memset(factor, 0, sizeof(factor));
for(int i = 0; i < n; i++) scanf("%d", &c[i]);
sort(c, c + n);
for(int i = n-1; i >= 0; i--) {
int x = c[i];
for(int k = 1; k*k <= x; k++)
if(x % k == 0) {
if(ans >= x/k) break;
if(factor[k]) ans = max(ans, k); else factor[k] = 1;
if(k*k == x) continue;
if(factor[x/k]) { ans = x/k; break; } else factor[x/k] = 1;
} else if(ans >= x/k) break;
}
printf("Case #%d: %d\n", kase, ans);
}
return 0;
}
1003
待补
1004
待补
时间: 2024-10-07 17:46:11