BestCoder-Round#38

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

BestCoder-Round#38的相关文章

BestCoder Round #38 1001 Four Inages Strategy 暴力

题意:给你空间中四个点,问你这四个点能否组成正方形. 解题思路:看两两之间的距离.根据正方形的性质求解. 解题代码: 1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2014年10月07日 星期二 00时41分28秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include&l

BestCoder Round #4 前两题 hdu 4931 4932

第一题太水了.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int a[6]; 7 int main(){ 8 int cas; 9 scanf( "%d", &cas ); 10 while( cas-- ){ 11 for( int i = 0; i <

BestCoder Round #88

传送门:BestCoder Round #88 分析: A题统计字符串中连续字串全为q的个数,预处理以下或加个cnt就好了: 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <ctime> 5 #include <cmath> 6 #include <iostream> 7 #include <algorithm> 8

BestCoder Round #14

Harry And Physical Teacher Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 38    Accepted Submission(s): 34 Problem Description As we all know, Harry Porter learns magic at Hogwarts School. How

BestCoder Round #2 1001 (简单处理)

题目链接 题意:给N条信息,每个信息代表有x个人从开始的时间 到 结束的时间在餐厅就餐, 问最少需要多少座位才能满足需要. 分析:由于时间只有24*60 所以把每个时间点放到 数组a中,并标记开始的时间+x, 结束的时间 -x.最后累加比较. 如果时间点太多的时候可以把时间点放到结构体里,排序,然后依次枚举结构体. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <

从lca到树链剖分 bestcoder round#45 1003

bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或),高手就不这么做了,直接树链剖分.为什么不能用lca,因为如果有树退化成链,那么每次询问的复杂度是O(n), 那么q次询问的时间复杂度是O(qn) 什么是树链剖分呢? 就是把树的边分成轻链和重链 http://blogsina.com.cn/s/blog_6974c8b20100zc61.htmlh

BestCoder Round #32

PM2.5 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 613    Accepted Submission(s): 326 Problem Description Nowadays we use content of PM2.5 to discribe the quality of air. The lower content of

hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 52 Problem Description A topological sort or topological ordering of a directed

Bestcoder BestCoder Round #28 A Missing number(查找缺失的合法数字)

Problem Description There is a permutation without two numbers in it, and now you know what numbers the permutation has. Please find the two numbers it lose. Input There is a number T shows there are T test cases below. (T<=10T≤10)For each test case

DP BestCoder Round #50 (div.2) 1003 The mook jong

题目传送门 1 /* 2 DP:这题赤裸裸的dp,dp[i][1/0]表示第i块板放木桩和不放木桩的方案数.状态转移方程: 3 dp[i][1] = dp[i-3][1] + dp[i-3][0] + 1; dp[i][0] = dp[i-1][1] + dp[i-1][0]; 4 比赛时二维dp写搓了,主要是边界情况的判断出错,比如dp[3][1] = 1,因为第3块放了木桩,其他地方不能再放,dp[3][0]同理 5 解释一下dp[i][1]的三种情况,可能是前面相隔2个放的方案或者是不放的