Codeforces Round #488 by NEAR (Div. 2)

A.

#include<cstdio>
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
int main()
{
    int n,m,i,j,k;
    set<int>s;
    cin>>n>>m;
    int num[15];
    for(i=1;i<=n;i++)cin>>num[i];
    for(i=1;i<=m;i++){
        cin>>j;s.insert(j);
    }
    for(i=1;i<=n;i++){
        if(s.count(num[i]))
            cout<<num[i]<<' ';
    }
    cout<<endl;

    return 0;
}

B.
拿一个堆模拟一下就行

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e5+5;
struct knight{
    int p,c,id;
    bool operator<(const knight&v)const{
        return c<v.c;
    }
}G[N];
bool cmp(knight a,knight b)
{
    return a.p<b.p;
}
int main()
{
    int n,k,i,j;
    cin>>n>>k;
    for(i=1;i<=n;i++)scanf("%d",&G[i].p),G[i].id=i;
    for(i=1;i<=n;i++)scanf("%d",&G[i].c);
    sort(G+1,G+1+n,cmp);
    priority_queue<knight,vector<knight> >que;
    vector<pair<int,long long> >p;
    for(i=1;i<=n;i++){
        long long ans=G[i].c;
        vector<knight>temp;
        int k1=k;
        while(!que.empty()&&k1--){
            ans+=que.top().c;temp.push_back(que.top());que.pop();
        }
        //cout<<ans<<' ';
        p.push_back(pair<int,long long>(G[i].id,ans));
        for(auto a:temp)que.push(a);
        que.push(G[i]);
    }
    sort(p.begin(),p.end());
    for(auto a:p)
        cout<<a.second<<' ';
    cout<<endl;

    return 0;
}

C.
计算几何板子题,注意有可能完全包含但是里面的顶点在外面的边上的情况,也就是没有交线但是有交点(不太严谨,大概是这个意思)

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include<iostream>
using namespace std;
const int MAXN = 100000;
const double EPS = 1e-8;

// 带误差比较
inline bool dcmp(double x, double y = 0)
{
    return fabs(x - y) <= EPS;
}
typedef struct Vec
{
    double x, y;

    Vec(double x = 0, double y = 0) : x(x), y(y) {}

    // 相加
    Vec operator+(const Vec &v) const
    {
        return Vec(x + v.x, y + v.y);
    }

    // 相减
    Vec operator-(const Vec &v) const
    {
        return Vec(x - v.x, y - v.y);
    }

    // 数乘(伸长、缩短)
    Vec operator*(double d) const
    {
        return Vec(x * d, y * d);
    }

    Vec operator/(const double d) const
    {
        return Vec(x / d, y / d);
    }

    // 范数,用来比较长度,等于长度的平方
    double norm() const
    {
        return x * x + y * y;
    }
} Pt;

// 点乘
double dot(const Vec &a, const Vec &b)
{
    return a.x * b.x + a.y * b.y;
}

// 叉乘
double cross(const Vec &a, const Vec &b)
{
    return a.x * b.y - a.y * b.x;
}

// 线段(Segment),用两个点表示
struct Seg
{
    Pt a, b;
    Seg(){};
    Seg(const Pt &a, const Pt &b) : a(a), b(b) {}

    // 线段包含点(点在线段上)
    bool include(const Pt &p)
    {
        // PA × PB = 0:PA 与 PB 共线,即点在线段所在的直线上
        // PA · PB = 0:PA 与 PB 方向不同(A 和 B 分别在 P 的两边),如果 PA · PB = 0 则 P = A 或 P = B
        return dcmp(cross(a - p, b - p)) && dot(a - p, b - p) <= 0;
    }
};

// 直线,用两个点表示
struct Line
{
    Pt a, b;

    Line() {} // 提供一个不需要参数的构造函数
    Line(const Pt &a, const Pt &b) : a(a), b(b) {}

    bool include(const Pt &p) const
    {
        return dcmp(cross(a - p, b - p));
    }

    // 两直线关系(交点个数)
    // 0 表示平行(无交点)
    // 1 表示相交(一个交点)
    // -1 表示重合(无数个交点)
    static int relation(const Line &a, const Line &b)
    {
        if (a.include(b.a) && a.include(b.b)) return -1;
        else if (dcmp(cross(a.b - a.a, b.b - b.a))) return 0;
        else return 1;
    }

    // 求两直线交点(需要保证两直线有交点)
    static Pt intersect(const Line &a, const Line &b)
    {
        double s1 = cross(b.a - a.a, b.b - a.a), s2 = cross(b.b - a.b, b.a - a.b);
        return a.a + (a.b - a.a) * s1 / (s1 + s2);
    }
};

struct Poly
{
    std::vector<Pt> pts;

    bool include(const Pt &p) const
    {
        int cnt = 0;
        // 判断与每条边有没有交点
        for (size_t i = 0; i < pts.size(); i++)
        {
            // 枚举相邻的每两个点
            const Pt &a = pts[i], &b = pts[(i + 1) % pts.size()];

            // 如果点 P 在边 AB 上
            if (Seg(a, b).include(p)) return true;

            // 详见图
            double d1 = a.y - p.y, d2 = b.y - p.y, tmp = cross(a - p, b - p);
            if ((tmp >= 0 && d1 >= 0 && d2 < 0) || (tmp <= 0 && d1 < 0 && d2 >= 0)) cnt++;
        }

        // 奇数的交点
        return cnt % 2 == 1;
    }

};
int main()
{
    int i,j,k;
    Vec a[4],b[4];
    for(i=0;i<4;i++)cin>>a[i].x>>a[i].y;
    for(i=0;i<4;i++)cin>>b[i].x>>b[i].y;
    Poly p1,p2;
    for(i=0;i<4;i++)p1.pts.push_back(a[i]);
    for(i=0;i<4;i++){
        if(p1.include(b[i])){
            cout<<"YES"<<endl;return 0;
        }
    }
    for(i=0;i<4;i++)p2.pts.push_back(b[i]);
    for(i=0;i<4;i++){
        if(p2.include(a[i])){
            cout<<"YES"<<endl;return 0;
        }
    }
    Line a1[4],b1[4];Seg a2[4],b2[4];
    for(i=0;i<4;i++){
        a2[i].a=a1[i].a=a[i];a2[i].b=a1[i].b=a[(i+1)%4];
        b2[i].a=b1[i].a=b[i];b2[i].b=b1[i].b=b[(i+1)%4];
    }
    for(i=0;i<4;i++){
        for(j=0;j<4;j++){
            int re=a1[i].relation(a1[i],b1[j]);
            if(re==1){
                Pt p=a1[i].intersect(a1[i],b1[j]);
                if(a2[i].include(p)&&b2[j].include(p)){
                    cout<<"YES"<<endl;return 0;
                }
            }
        }
    }
    cout<<"NO"<<endl;

    return 0;
}

E.
非常暴力的做法,我们枚举左边的船与右边的船,每一对可以在中间确定一个点,然后我们统计如果小船放在这个点,会有多少船被摧毁,这可以用一个bitset来表示,最后我们要找两个最适合小船的位置,那么就枚举刚刚统计的bitset的结果,或一下求最大值即可。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<bitset>
#include<vector>
using namespace std;
vector<bitset<125>>pos;
bitset<125>temp;
vector<int>l,r;
int main()
{
    int n,m,i,j,k;
    cin>>n>>m;
    for(i=1;i<=n;i++){
        cin>>j;l.push_back(j*2);//原本担心/2会出小数,其实根本不用
    }
    //sort(l.begin(),l.end());
    for(i=1;i<=m;i++){
        cin>>j;r.push_back(j*2);
    }
    //sort(r.begin(),r.end());
    for(i=0;i<n;i++)
        for(j=0;j<m;j++){
        int now=(l[i]+r[j]);
        temp.reset();
        for(k=0;k<n;k++)
            for(int q=0;q<m;q++){
            if(l[k]+r[q]==now){
                temp.set(k);temp.set(q+60);
            }
        }
        pos.push_back(temp);
    }
    int ans=0;
    for(auto a:pos)
        for(auto b:pos){
        temp=a|b;
        ans=max(ans,(int)temp.count());
    }
    cout<<ans<<endl;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值