• 【2019 CCPC 江西省赛】Trap 枚举


    C - Trap

    题意

    给出 (n) 条边,问能组成几种等腰梯形。要满足一下要求:

    1. 不能是矩形
    2. 所有边长的 gcd 是1
    3. 全等的梯形只算一次

    思路

    枚举梯形的腰 (x) 和顶 (y),可以求出底的范围为:([y+1,2*x+y-1])

    因为还有一个条件为 (gcd) 为 1,那么我们可以预处理出一个数组 (vec[N][N])(vec[i]) 存放和 (i) 互质的所有边长。

    对于腰 (x) 和顶 (y)我们在 vec[(gcd(x,y))] 中找在区间 ([y+1,2*x+y-1]) 的个数,这时候特判一下 (x)(y) 的个数避免多算。

    比赛的时候因为我读错题意,以为矩形也可以,疯狂WA。。。赛后对拍发现不对劲,修改一下底的范围就过了。

    代码

    /*
     * @Autor: valk
     * @Date: 2020-08-21 11:06:28
     * @LastEditTime: 2020-10-16 20:47:12
     * @Description: 如果邪恶  是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
     */
    #include <algorithm>
    #include <iostream>
    #include <map>
    #include <math.h>
    #include <queue>
    #include <set>
    #include <stack>
    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <vector>
    #define emplace_back push_back
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int mod = 1e9 + 7;
    const int seed = 12289;
    const double eps = 1e-6;
    const ll inf = 0x3f3f3f3f3f3f3f3f;
    const int N = 1e5 + 10;
    
    int arr[N], num[N];
    vector<int> vec[N];
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &arr[i]);
            num[arr[i]]++;
        }
        sort(arr + 1, arr + 1 + n);
        n = unique(arr + 1, arr + 1 + n) - arr - 1;
        for (int i = 1; i <= 10000; i++) {
            for (int j = 1; j <= n; j++) {
                if (__gcd(i, arr[j]) == 1) {
                    vec[i].pb(arr[j]);
                }
            }
        }
        ll ans = 0;
        for (int i = 1; i <= n; i++) { //腰
            if (num[arr[i]] < 2)
                continue;
            for (int j = 1; j <= n; j++) { //顶
                if (i == j && num[arr[i]] < 3)
                    continue;
                int l = arr[j] + 1, r = arr[j] + 2 * arr[i] - 1;
                int gcd = __gcd(arr[i], arr[j]);
                int R = upper_bound(vec[gcd].begin(), vec[gcd].end(), r) - vec[gcd].begin();
                int L = upper_bound(vec[gcd].begin(), vec[gcd].end(), l - 1) - vec[gcd].begin();
                int temp = R - L;
                if (num[arr[j]] == 1 && __gcd(arr[j], gcd) == 1 && arr[j] >= l && arr[j] <= r) {
                    temp--;
                }//如果边长为arr[j]的边只有一条,并且还被计算到了底中,那么要减去这个
                if (num[arr[i]] == 2 && __gcd(gcd, arr[i]) == 1 && arr[i] >= l && arr[i] <= r) {
                    temp--;
                }//腰同理
                ans += temp;
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    /*
    6
    1 1 10 8 8 5 
    */
    
  • 相关阅读:
    每日软件进度报告—12月10日
    每日软件进度报告—12月9日
    每日软件进度报告—12月8日
    每日软件进度报告—12月7日
    每日软件进度报告—12月6日
    每日软件进度报告—12月5日
    每日软件进度报告—12月4日
    每日软件进度报告—12月3日
    四则运算1
    对苹果自带输入法的测评
  • 原文地址:https://www.cnblogs.com/valk3/p/13832331.html
Copyright © 2020-2023  润新知