【考试总结】2021-03-14
A.选拔赛
把两个数组拍一下序之后发现 的和一共只有 个,那么离散下来枚举前 个和的最小值
设 calc(i,j)
表示前 个数的和最小值和后面的数的和的最大值
对于当前的最小值,每个 的 能选的 都是一个的后缀,得到这个后缀是 的
考虑这些后缀的长度是递减的,那么直接按照排序 减掉前面的数量就行
设 表示前 个 中有 个被使用于前 个数
记录每个 在当前的 中可以在两边所取到的区间长度
这样分是不是加入前面 个数进行两种转移即可
B.跳跃
用线段树对 维护每 步能到的区间
其实对于这个限制,如果存在 使得 有一个点的 那么就成立,对于左边也是一样的
使用前后缀进行优化
在从大到小维护答案是不是可以被插入时,可以按照建树的方法求当前待拓展的答案的线段树
这样的话总的复杂度是
C.切蛋糕
考虑对所有直接求一个交集,再和原图形求一个交集
这个需要半平面交,剩下的按照极角排序之后在大力分类讨论扫一扫就行了
然而不会半平面交,只能打 的暴力
半平面交
平面上有一些凸多边形,求这些凸多边形的交(其实求出来并了以后周长和面积就可做了)
注意:叉积为 a.x*b.y-b.x*a.y
如果大于 说明两个向量成锐角,等于 表明垂直,小于 为钝角
那么做法如下:
先把第一个多边形当做 ,对于新加入的每个多边形,依次加入所有边
加入边时枚举每个原来的边判断是不是有交点,如果有就求交点新加入直线
然后对于 的做法,先把所有线按照极角排序,然后维护一个单调队列
还是分割平面,考虑对于原答案的更改一定是一定是删掉极角最大或小的一些区间,那么直接弹就好了
然后得到这个做法之后,为了避免分类讨论,我们把整个圆分成 个,把这些段弧当做直线考虑
然后一起做半平面交,把弧上的边打上标记
注意,使用结构体函数的时候会直接给 一个随机值,记得重置
const int N=100010;
const double pi=acos(-1);
struct node{
double x,y;
node(){}
node(double xx,double yy){x=xx; y=yy; return ;}
node operator +(const node &a)const{return node(x+a.x,y+a.y);}
node operator -(const node &a)const{return node(x-a.x,y-a.y);}
node operator *(const node &a)const{return node(x*a.x-y*a.y,x*a.y+y*a.x);}
inline double dist(){return sqrt(x*x+y*y);}
node operator *(const double &a)const{return node(x*a,y*a);}
}p[N];
int k=10000,h=1,t,n,cnt; double R,ans[2];
inline double cross(node a,node b){return a.x*b.y-a.y*b.x;}
struct line{
node st,ed; double ang;
bool rnd;
line(){}
line(node a,node b){st=a; ed=b; ang=atan2(ed.y-st.y,ed.x-st.x); rnd=0; return ;}
bool operator <(const line &a)const{
if(ang==a.ang) return cross(ed-st,a.st-st)<0;
else ang<a.ang;
}
}l[N],q[N];
inline node get(line a,line b){
node da=a.ed-a.st,db=b.ed-b.st;
return a.st+da*(cross(db,b.st-a.st)/cross(db,da));
}
signed main(){
freopen("cut.in","r",stdin); freopen("cut.out","w",stdout);
n=read(); scanf("%lf\n",&R);
for(reg int i=1;i<=n;++i){
double a,h; scanf("%lf%lf",&a,&h);
l[++cnt]=line(node(cos(a*pi/180),sin(a*pi/180))*h,node(cos(a*pi/180),sin(a*pi/180))*h+node(cos(a*pi/180+pi/2),sin(a*pi/180+pi/2))); q[i].rnd=0;
}
for(reg int i=0;i<k;++i){
node p1=node(cos(pi*2/k*i),sin(pi*2/k*i));
node p2=node(cos(pi*2/k*(i+1)),sin(pi*2/k*(i+1)));
l[++cnt]=line(p1*R,p2*R);
l[cnt].rnd=1;
}
sort(l+1,l+cnt+1);
for(reg int i=1;i<=cnt;++i){
if(i!=1&&l[i].ang==l[i-1].ang) continue;
while(h<t&&cross(l[i].ed-l[i].st,p[t-1]-l[i].st)<0) --t;
while(h<t&&cross(l[i].ed-l[i].st,p[h]-l[i].st)<0) ++h;
q[++t]=l[i];
if(h<t) p[t-1]=get(q[t-1],q[t]);
}
while(h<t&&cross(q[h].ed-q[h].st,p[t-1]-q[h].st)<0) --t;
p[t]=get(q[h],q[t]); p[h-1]=p[t];
for(reg int i=h;i<=t;++i){
if(q[i].rnd) ans[1]+=(p[i-1]-p[i]).dist();
else ans[0]+=(p[i-1]-p[i]).dist();
}
printf("%.10lf %.10lf\n",ans[0],ans[1]);
return 0;
}
恶心吗?不恶心。 不恶心吗?恶心。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律