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;
}