2020牛客寒假算法基础集训营2

2020牛客寒假算法基础集训营2

D 数三角

D

题解

单纯数三角形,数据小 n 3 n^3 n3就能过.
但是如果判断三角形时,用判断角度的方法,会超时
acos这玩意会超时也挺蛋疼的

#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
const double pi = acos(-1.0);
const double eps = 1e-12;
typedef long long ll;
const ll INF = LLONG_MAX;
const ll ENF = LLONG_MIN;
const int MAXN = 1e3 + 10;
const int inf = __INT_MAX__;
const int enf = INT_MIN;

typedef struct point vec;
struct point { //点的基本数据结构
    double x, y;
    double poe;
    point(double _x = 0, double _y = 0)
        : x(_x)
        , y(_y)
    {
    }
    double len() //模长
    {
        return sqrt(x * x + y * y);
    }
    vec chuizhi()
    {
        return vec(-y, x);
    }
    double operator*(const point& i_T) const //点积
    {
        return x * i_T.x + y * i_T.y;
    }
    double operator^(const point& i_T) const //叉积
    {
        return x * i_T.y - y * i_T.x;
    }
    point operator*(double u) const
    {
        return point(x * u, y * u);
    }
    bool operator==(const point& i_T) const
    {
        return fabs(x - i_T.x) < eps && fabs(y - i_T.y) < eps;
    }
    point operator/(double u) const
    {
        return point(x / u, y / u);
    }
    point operator+(const point& i_T)
    {
        return point(x + i_T.x, y + i_T.y);
    }
    point operator-(const point& i_T)
    {
        return point(x - i_T.x, y - i_T.y);
    }
    friend bool operator<(point a, point b)
    {
        return fabs(a.y - b.y) < eps ? a.x < b.x : a.y < b.y;
    }
    void atn2()
    {
        poe = atan2(y, x);
    }
    friend ostream& operator<<(ostream& out, point& a)
    {
        //cout << a.x << ' ' << a.y;
        printf("%.8f %.8f", a.x, a.y);
        return out;
    }
    friend istream& operator>>(istream& in, point& a)
    {
        scanf("%lf%lf", &a.x, &a.y);
        return in;
    }
};
point p[MAXN];
double jiajiao(vec a, vec b)
{
    return pi - acos((a * b) / ((a).len() * (b).len()));
}
bool check(point a, point b, point c)
{
    double a1[] = { (a - b) * (a - b), (b - c) * (b - c), (c - a) * (c - a) };
    sort(a1, a1 + 3);
    if (sqrt(a1[0]) + sqrt(a1[1]) > sqrt(a1[2]) && a1[0] + a1[1] < a1[2])
        return 1;
    return 0;
}
int main()
{
    int n, sum = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> p[i];
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
            for (int k = j + 1; k <= n; k++)
                if (check(p[i], p[j], p[k]))
                    sum++;
    cout << sum << endl;
    return 0;
}

E 做计数

E

题解

i + j = k \sqrt{i}+\sqrt{j}=\sqrt{k} i +j =k 平方后为
i + 2 i j + j = k i+2\sqrt{ij}+j=k i+2ij +j=k,然后我们可知 i j ij ij为整数, 2 i j = k − i − j 2\sqrt{ij}=k-i-j 2ij =kij也为整数,然后假设 i j = v 2 ij=v^2 ij=v2,那么 v v v是个整数
i j = v 2 < n ij=v^2<n ij=v2<n
可知枚举即可

#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
const double pi = acos(-1.0);
const double eps = 1e-12;
typedef long long ll;
const ll INF = LLONG_MAX;
const ll ENF = LLONG_MIN;
const int MAXN = 1e3 + 10;
const int inf = __INT_MAX__;
const int enf = INT_MIN;

int main()
{
    int n;
    cin >> n;
    int ans = 0;
    for (int i = 1; i * i <= n; i++)
        for (int j = 1; j <= i; j++)
            if (i * i % j == 0) {
                if (j == i)
                    ans--;
                ans += 2;
            }

    cout << ans << endl;
    return 0;
}

I 建通道

I

题解

首先,相同的数字之间消费为0,去重
结合题目,为了使答案最小,便是找最小二进制位,且该位有0也有1才行
然后就没有然后了

#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
const double pi = acos(-1.0);
const double eps = 1e-12;
typedef long long ll;
const ll INF = LLONG_MAX;
const ll ENF = LLONG_MIN;
const int MAXN = 2e5 + 10;
const int inf = __INT_MAX__;
const int enf = INT_MIN;

int a[MAXN];
int main()
{
    int n, v1 = 0, v0 = inf;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a, a + n);
    n = unique(a, a + n) - a;
    for (int i = 0; i < n; i++) //将所有出现过的1的位置都记下来
        v1 |= a[i];
    for (int i = 0; i < n; i++) //存在某一位又有0又有1,那么v0该位为0
        v0 &= a[i];
    v1 ^= v0; //保留符合有0也有1的位置
    int ans = 0;

    for (int i = 0; i <= 30; i++) {
        int cur = 1 << i;
        if (v1 & cur) {
            ans = cur * (n - 1);
            break;
        }
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值