[几何 扫描线] LOJ#6260. 「CodePlus 2017 12 月赛」寄蒜几盒

news/2024/11/8 18:44:00/

直线很少,把交点算出来扫描线

多边形的数量是 O(n2) O ( n 2 ) 的,因为是平面图,所以顶点的总数也是 O(n2) O ( n 2 ) 的,搞一搞就好了

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#define eq(a,b) (fabs(a-b)<eps)
#define IN(x) ((x)>=-L && (x)<=L)
#define pb push_backusing namespace std;typedef double ld;const int N=510,M=1000010;
const ld eps=1e-7;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}inline void read(int &x){char c=nc(); x=0;for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}inline void read(ld &x){char c=nc(); int f=1,flg=0,dv=1; x=0;for(;c>'9'||c<'0';c=nc())if(c=='-')f=-1;for(;c>='0'&&c<='9' || c=='.';x=x*10+c-'0',c=nc(),dv=flg?dv*10:dv)if(c=='.'){flg=1; c=nc();}x/=dv; x*=f;
}ld L,l,r;
int cnt,tot,t,n,m,id[N];
ld A[N],B[N],C[N];struct Point{ld x,y;Point(ld _x=0,ld _y=0):x(_x),y(_y){}friend bool operator <(const Point &a,const Point &b){if(a==b) return 0;if(!eq(a.x,b.x)) return a.x<b.x;return a.y<b.y;}friend bool operator ==(const Point &a,const Point &b){return eq(a.x,b.x) && eq(a.y,b.y);}
};struct node{Point x; int g,a,b;friend bool operator <(const node &a,const node &b){if(a.x==b.x) return a.a<b.a;return a.x<b.x;}
}a[M];vector<ld> border; 
vector<Point> polygon[M];inline Point Cross(int x,int y){ld k1=-A[x]/B[x],d1=-C[x]/B[x],k2=-A[y]/B[y],d2=-C[y]/B[y];if(eq(k1,k2)) return Point(-1e20,-1e20);Point ret; ret.x=(d1-d2)/(k2-k1); ret.y=k1*ret.x+d1;return ret;
}int ans[M];inline ld f(int g,ld x){return -(A[g]*x+C[g])/B[g];
}inline bool cmp(const int &a,const int &b){if(!eq(f(a,l),f(b,l))) return f(a,l)<f(b,l);return -A[a]/B[a]>-A[b]/B[b];
}int p=1,rk[N],pnum[N];inline void work(){for(int i=1;i<t;i++){++cnt;polygon[cnt].pb(Point(l,f(id[i],l)));polygon[cnt].pb(Point(l,f(id[i+1],l)));pnum[i]=cnt;}for(;p<=tot;p++){if(a[p].x.x>r) break;if(a[p].g){int l=1,r=t,res,mid;while(l<=r) f(id[mid=l+r>>1],a[p].x.x)<a[p].x.y?l=(res=mid)+1:r=mid-1;ans[a[p].g]=pnum[res];continue;}int np=p,revL=min(rk[a[p].a],rk[a[p].b]),revR=max(rk[a[p].a],rk[a[p].b]);while(np<tot && a[np+1].x==a[p].x){np++;revL=min(min(rk[a[np].a],rk[a[np].b]),revL);revR=max(max(rk[a[np].a],rk[a[np].b]),revR);}if(pnum[revL-1])polygon[pnum[revL-1]].pb(a[p].x);if(pnum[revR])polygon[pnum[revR]].pb(a[p].x);reverse(id+revL,id+revR+1);for(int i=revL;i<=revR;i++){rk[id[i]]=i;if(i==revR) break;polygon[pnum[i]].pb(a[p].x);pnum[i]=++cnt;polygon[cnt].pb(a[p].x);}p=np;}for(int i=1;i<t;i++){polygon[pnum[i]].pb(Point(r,f(id[i],r)));polygon[pnum[i]].pb(Point(r,f(id[i+1],r)));}
}ld size[M];
int vis[M];Point s;inline bool cmp1(const Point &a,const Point &b){return (a.y-s.y)*(b.x-s.x)<(b.y-s.y)*(a.x-s.x);
}inline ld cross(const Point &a,const Point &b){return (a.x-s.x)*(b.y-s.y)-(a.y-s.y)*(b.x-s.x);
}inline ld calc(int x){vector<Point> &c=polygon[x];for(int i=1;i<c.size();i++)if(c[i]<c[0]) swap(c[i],c[0]);s=c[0]; sort(c.begin()+1,c.end(),cmp1);ld ret=0;for(int i=1;i<c.size()-1;i++)ret+=cross(c[i],c[i+1]);return ret/2;
}void PutAns(int x){if(x>=10) PutAns(x/10); putchar(x%10+'0');
}int main(){freopen("1.in","r",stdin);freopen("1.out","w",stdout);read(n); read(m); read(L);for(int i=1;i<=n;i++){read(A[i]); read(B[i]); read(C[i]);if(!eq(B[i],0))id[++t]=i;else if(IN(C[i]/A[i]))border.pb(-C[i]/A[i]);}id[++t]=n+1; A[n+1]=0; B[n+1]=1; C[n+1]=L;id[++t]=n+2; A[n+2]=0; B[n+2]=1; C[n+2]=-L;border.pb(-L); border.pb(L);sort(border.begin(),border.end());l=-L; sort(id+1,id+1+t,cmp);for(int i=1;i<=t;i++) rk[id[i]]=i;for(int i=1;i<=t;i++)for(int j=i+1;j<=t;j++){Point cur=Cross(id[i],id[j]);//printf("%d %d %.2lf %.2lf\n",i,j,cur.x,cur.y);if(!IN(cur.x)) continue;++tot; a[tot].x=cur; a[tot].a=id[i]; a[tot].b=id[j]; a[tot].g=0;}for(int i=1;i<=m;i++){++tot; read(a[tot].x.x); read(a[tot].x.y);a[tot].g=i;}sort(a+1,a+1+tot);for(int i=0;i<border.size()-1;i++){l=border[i]; r=border[i+1];if(eq(l,r)) continue;work();}/*for(int i=1;i<=cnt;i++){printf("%d : ",i);for(auto x : polygon[i]) printf("%.2lf %.2lf\n",x.x,x.y);putchar('\n');}*/for(int i=1;i<=m;i++){if(!vis[ans[i]])vis[ans[i]]=1,size[ans[i]]=calc(ans[i]);PutAns((int)(size[ans[i]]+0.005)); putchar('.');int r=(long long)(size[ans[i]]*100+0.5)%100;if(r<10) putchar('0');PutAns(r); putchar('\n');//printf("%.2lf\n",size[ans[i]]);}return 0;
}

http://www.ppmy.cn/news/147167.html

相关文章

MT6260D SPI 的问题,求高手探讨

BB搭载了一个指纹芯片&#xff0c;需要SPI通讯&#xff0c;看了下代码&#xff0c;SPI就提供了几个接口&#xff0c;具体怎么用看不透彻&#xff0c;按照自己的思路写了一个&#xff0c;发现写数据时连信号都没有&#xff0c;有木有人整过这方面的东西经验共享一下。 设计用的S…

6260环境配置问题求助

RVCT 3.1 参考 SOP_Third_Party_package_installation.pdf 安装 其他软件。 编译出现如下问题&#xff1a; 用了60d_v1 v5的mtk软件编译出现一样的问题 求助&#xff0c;各位有没有遇到过这类问题。

微信小程序:VM6260:1 vdSyncBatch 数据传输长度为 1623104 已经超过最大长度 1048576

setData 单次设置的数据不能超过1024kB&#xff0c;请尽量避免一次设置过多的数据。

MTK6260平台上SPI(3line2lane)屏的调试总结

这次的调试过程花的时间相对来说比较久&#xff0c;3-4天。 总结一下导致的主要原因就是mtk的资料不齐全&#xff0c;当然另外一个原因也是自己的知识体系不完善。 为什么说是mtk的资料不齐全导致&#xff1f;做mtk的人都知道&#xff0c;mtk做得比较傻瓜化&#xff0c;这样就…

mtk 6260 group-cui

从互芯转到mtk&#xff0c;发现最大的变化&#xff0c;是group这块。 mmi_frm_group_creat mmi_frm_group_entry mmi_frm_group_close CUI( COMMON UI) cui_menu_create cui_menu_run cui_menu_close 要好好研究下 PlutoFW10A_training_09A_TO_10A.pdf 转篇文章学习下 …

LC-6260. 矩阵查询可获得的最大分数(最小堆,并查集+离线(海平面上升问题))【周赛323】

6260. 矩阵查询可获得的最大分数 难度困难7 给你一个大小为 m x n 的整数矩阵 grid 和一个大小为 k 的数组 queries 。 找出一个大小为 k 的数组 answer &#xff0c;且满足对于每个整数 queres[i] &#xff0c;你从矩阵 左上角 单元格开始&#xff0c;重复以下过程&#xf…

MT6260D ROM情况介绍

mt6260d总的rom大小为&#xff1a;3694592 bytes 28.1875Mb 不做任何修改编译原始文件rom大小为&#xff1a;2599536 bytes 19.8328857421875Mb 分辨率为128X128 修改分辨率为240X320&#xff0c;打开中文的rom大小为&#xff1a; 2781176 bytes 21.218688…

MTK6260短信猫模块参数

MTK6260短信猫模块参数&#xff1a; ★ 处理器&#xff1a;MTK ★ 制式频段 四频850/900/1800/1900MHz ★ GPRS mobile station class B 标准 ★ 速率 GSM CS&#xff1a;UL 14.4 kbits/DL 14.4 kbits ★ GPRS&#xff1a;UL 42.8 kbits/DL 85.6 kbits ★ 协议&#xff1a…