2018 BUPT Winter Training #6 Div.2
2018-03-07 22:52
363 查看
A - Intersecting Lines
rt,求相交直线。#include <iostream> #include <cstdlib> #include <cmath> #include <iomanip> #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) using namespace std; const double eps = 1e-6; struct Point { double x,y; Point(){} Point(double _x,double _y){x = _x;y = _y;} Point get(){cin>>x>>y;return Point(x,y);} Point operator+(const Point &b)const{return Point(x+b.x,y+b.y);} Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);} double operator*(const Point &b)const{return x*b.x+y*b.y;} double operator^(const Point &b)const {return x*b.y-y*b.x;} }P[5]; int main(void) { int T,t; cin>>T; cout<<"INTERSECTING LINES OUTPUT\n"; while(T--){ FF(i,1,4)P[i].get(); if(fabs((P[2]-P[1])^(P[4]-P[3]))<eps){ if(fabs((P[3]-P[1])^(P[4]-P[1]))<eps)cout<<"LINE"<<endl; else cout<<"NONE"<<endl; }else{ double a1=P[1].y-P[2].y,a2=P[3].y-P[4].y; double b1=P[2].x-P[1].x,b2=P[4].x-P[3].x; double c1=P[1]^P[2],c2=P[3]^P[4]; double D=a1*b2-a2*b1; cout<<fixed<<"POINT "<<setprecision(2)<<(b1*c2-b2*c1)/D<<" "<<(a2*c1-a1*c2)/D<<endl; } } cout<<"END OF OUTPUT\n"; }
B - The Doors
暴力枚举线段相交…这就很不优美了。#include <iostream> #include <cmath> #include <cstring> #include <cstdlib> #include <vector> #include <utility> #include <queue> #include <iomanip> #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) #define TRV(_i,_V) for(int _i=(_V).size()-1;_i+1;_i--) #define PB push_back #define all(x) x.begin(),x.end() #define MP make_pair #define sec second #define fir first using namespace std; const double eps=1e-7; int sgn(double x){ return (fabs(x)>=eps)*x; } struct Point { double x,y; Point(){} Point(double _x,double _y){x=_x;y=_y;} Point get(){cin>>x>>y;return Point(x,y);} Point operator+(const Point &b)const{return Point(x+b.x,y+b.y);} Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);} double operator*(const Point &b)const{return x*b.x+y*b.y;} double operator^(const Point &b)const {return x*b.y-y*b.x;} }; struct Line { Point a,b; Line(){} Line(Point _a,Point _b){a=_a;b=_b;} }; typedef pair<double,Line> W; vector<int> ade[150]; vector<W> wall; vector<Point> P; inline double dis(int x,int y){return sqrt((P[x].x-P[y].x)*(P[x].x-P[y].x)+(P[x].y-P[y].y)*(P[x].y-P[y].y));} inline bool SegCross(Line a,Line b){ return ((a.a-b.a)^(a.b-b.a))*((a.a-b.b)^(a.b-b.b))<0&&((b.a-a.a)^(b.b-a.a))*((b.a-a.b)^(b.b-a.b))<0; } bool check(int x,int y){ Line l=Line(P[x],P[y]); double m; TRV(w,wall){ if(P[x].x<=wall[w].fir&&wall[w].fir<=P[y].x&&SegCross(l,wall[w].sec))return 0; } return 1; } typedef pair<double,int> pdi; bool vis[120]; int main(){ pdi t;int n,e;double x,y1,y2,y3,y4;Point start=Point(0,5),end=Point(10,5); ios::sync_with_stdio(false); while(cin>>n&&n!=-1){ P.clear();wall.clear(); F(i,(n<<2)+10)ade[i].clear(); memset(vis,0,sizeof(vis)); priority_queue<pdi,vector<pdi>,greater<pdi> > q; P.PB(start); F(i,n){ cin>>x>>y1>>y2>>y3>>y4; P.PB(Point(x,y1)); P.PB(Point(x,y2)); P.PB(Point(x,y3)); P.PB(Point(x,y4)); e=(i<<2)+1; wall.PB(MP(x,Line(Point(x,0),P[e]))); wall.PB(MP(x,Line(P[e+1],P[e+2]))); wall.PB(MP(x,Line(P[e+3],Point(x,10)))); } e=P.size(); P.PB(end); TRV(i,P)F(j,i)if(check(j,i))ade[j].PB(i); q.push(MP(0,0)); while(!q.empty()){ t=q.top();q.pop(); if(vis[t.sec])continue; vis[t.sec]=1; if(t.sec==e)break; TRV(i,ade[t.sec])q.push(MP(t.fir+dis(t.sec,ade[t.sec][i]),ade[t.sec][i])); } cout<<fixed<<setprecision(2)<<t.fir<<endl; } }
C - Space Ant
求连接点最多的螺旋线,用极角排序就ok了。#include <iostream> #include <cmath> #include <cstdlib> #include <algorithm> #include <iomanip> #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) using namespace std; const double eps=1e-8; inline double sgn(double x){return (fabs(x)>=eps)*x;} struct Point { double x,y; int id; Point(){} Point(double _x,double _y,int _id=0){id=_id;x = _x;y = _y;} Point get(){cin>>id>>x>>y;return Point(x,y,id);} bool operator<(const Point &b)const{return y<b.y||(y==b.y&&x<b.x);} Point operator+(const Point &b)const{return Point(x+b.x,y+b.y);} Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);} double operator*(const Point &b)const{return x*b.x+y*b.y;} double operator^(const Point &b)const {return x*b.y-y*b.x;} }P[105]; //inline double dis(int x,int y){return sqrt((P[x]-P[y])*(P[x]-P[y]));} //inline double dis(int x,int y){return (P[x]-P[y])*(P[x]-P[y]);} //inline double dis(Point x,Point y){return sqrt((x-y)*(x-y));} inline double dis(Point x,Point y){return (x-y)*(x-y);} int cur; bool cmp(Point x,Point y){ double t=sgn((x-P[cur])^(y-P[cur])); return t==0&&dis(x,P[cur])<dis(y,P[cur])||t>0; } int main(){ int T,n; ios::sync_with_stdio(false); P[0]=Point(0,0); for(cin>>T;T--;){ cin>>n; FF(i,1,n){ P[i].get(); if(P[i]<P[1])swap(P[1],P[i]); } cur=1; cout<<n<<" "<<P[1].id; FF(i,2,n){sort(P+i,P+n+1,cmp);cout<<" "<<P[cur=i].id;} cout<<endl; } }
D…阵亡
E - Grandpa’s Estate
因为已经是个凸包了,所以不需要判凸包。极角排序后判断同一个边上是否至少有三个点即可。坑爹的是,这道题我WA6次,原因是”YES”“NO”写成了”Yes”“No”…真是破坏了我补div2#6的心情…所以我才没怎么补这次比赛的题了..有时间再把没过的题好好过一遍吧。#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) using namespace std; const double eps=1e-7; double sgn(double x){ return (fabs(x)>=eps)*x; } struct Point { double x,y; Point(){} Point(double _x,double _y){x = _x;y = _y;} Point operator+(const Point &b)const{return Point(x+b.x,y+b.y);} Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);} double operator*(const Point &b)const{return x*b.x+y*b.y;} double operator^(const Point &b)const {return x*b.y-y*b.x;} bool operator==(const Point &b)const{return x==b.x&&y==b.y;} }P[1005],X; inline double dis(Point x,Point y){return sqrt((x-y)*(x-y));} bool cmp(Point x,Point y){ double f=(x-X)^(y-X); if(f>0)return 1; if(f==0&&dis(x,X)<dis(y,X))return 1; return 0; } bool Judge(int n){ int curr=0; bool FIND=0,JUDGE=0; Point Vec,pre; for(;;){ if(curr==n)return 1; Vec=P[curr+1]-P[curr]; if(FIND&&(pre^Vec)==0){ pre=Vec;curr++;continue; }else FIND=0; if(JUDGE)if((pre^Vec)!=0)return 0;else FIND=1,JUDGE=0; else JUDGE=1; pre=Vec;curr++; } } int main(){ int T,n; for(scanf("%d",&T);T--;){ scanf("%d",&n); memset(P,0,sizeof(P)); F(i,n){ scanf("%lf%lf",&P[i].x,&P[i].y); if(P[i].y<P[0].y||P[i].y==P[0].y&&P[i].x<P[0].x)swap(P[0],P[i]); } X=P[0]; sort(P,P+n,cmp); P =P[0]; if(n<6){puts("NO");continue;} if(((P -P[n-1])^(P[n-1]-P[n-2]))!=0){puts("NO");continue;} X=P[n-1]; while(((P -P[n-1])^(P[n-1]-P[n-2]))==0)n--; n--;P =X; puts(Judge(n)?"YES":"NO"); } }
F..先算了
G - Circle and Points
3200ms:思路是枚举所有可能的圆。1400ms:因为单位圆的半径是1,判断不需要sqrt,这样效率就大幅升高了。
1200ms:增加离散化评价,如果求得圆心周围九个格子的点还不如ans,就不需要判断了。
//3200ms #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #define eps 1e-8 #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) using namespace std; struct Point { double x,y; Point(){} Point(double _x,double _y){x = _x;y = _y;} Point operator+(const Point &b)const{return Point(x+b.x,y+b.y);} Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);} Point operator/(const double k)const{return Point(x/k,y/k);} double operator*(const Point &b)const{return x*b.x+y*b.y;} double operator^(const Point &b)const {return x*b.y-y*b.x;} bool operator==(const Point &b)const{return x==b.x&&y==b.y;} bool operator<(const Point &b)const{return x<b.x||x==b.x&&y<b.y;} }P[305]; inline double dis(Point x,Point y){return sqrt((x-y)*(x-y));} //1400ms:用下面dis2函数代替dis判断 //inline double dis2(Point x,Point y){return (x-y)*(x-y);} void getmid(Point P1,Point P2,Point ¢er) { Point mid; mid.x=(P1.x+P2.x)/2.0; mid.y=(P1.y+P2.y)/2.0; double angle=atan2(P1.x-P2.x,P2.y-P1.y); double dcm=sqrt(1-dis(P1,mid)*dis(P1,mid)); center.x=mid.x+dcm*cos(angle); center.y=mid.y+dcm*sin(angle); } int main() { int n,i,j,k; while(scanf("%d",&n),n){ F(i,n)scanf("%lf%lf",&P[i].x,&P[i].y); int ans=1; F(i,n){ for(j=i+1; j<n; ++j) { if(dis(P[i],P[j])>2.0)continue; Point center; getmid(P[i],P[j],center); int cnt=0; F(k,n){ if(fabs(P[k].x-center.x)>1||fabs(P[k].y-center.y)>1)continue; if(dis(P[k],center)<1.0+eps)cnt++; } if(ans<cnt)ans=cnt; } } printf("%d\n",ans); } return 0; }
//1200ms #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include <map> #include<algorithm> #define eps 1e-8 #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) using namespace std; struct Point { double x,y; Point(){} Point(double _x,double _y){x = _x;y = _y;} Point operator+(const Point &b)const{return Point(x+b.x,y+b.y);} Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);} Point operator/(const double k)const{return Point(x/k,y/k);} double operator*(const Point &b)const{return x*b.x+y*b.y;} double operator^(const Point &b)const {return x*b.y-y*b.x;} bool operator==(const Point &b)const{return x==b.x&&y==b.y;} bool operator<(const Point &b)const{return x<b.x||x==b.x&&y<b.y;} }A[305]; int conj[12][12]; inline double dis(Point x,Point y){return sqrt((x-y)*(x-y));} inline double dis2(Point x,Point y){return (x-y)*(x-y);} void getmid(Point P1,Point P2,Point ¢er) { Point mid; mid.x=(P1.x+P2.x)/2.0; mid.y=(P1.y+P2.y)/2.0; double angle=atan2(P1.x-P2.x,P2.y-P1.y); double dcm=sqrt(1-dis(P1,mid)*dis(P1,mid)); center.x=mid.x+dcm*cos(angle); center.y=mid.y+dcm*sin(angle); } int main() { int n,i,j,k,ttt; while(scanf("%d",&n),n){ memset(conj,0,sizeof(conj)); F(i,n){ scanf("%lf%lf",&A[i].x,&A[i].y); conj[(int)A[i].x+1][(int)A[i].y+1]++; } int ans=1,x,y; F(i,n){ for(j=i+1; j<n; ++j) { if(dis(A[i],A[j])>2.0)continue; Point center; getmid(A[i],A[j],center); x=(int)(center.x);y=(int)(center.y); if(conj[x+1][y+1]+conj[x][y]+conj[x][y+1]+conj[x][y+2]+conj[x+1][y]+conj[x+1][y+2]+conj[x+2][y]+conj[x+2][y+1]+conj[x+2][y+2]<ans)continue; int cnt=0; F(k,n){ if(dis2(A[k],center)<1.0+eps)cnt++; } if(ans<cnt)ans=cnt; } } printf("%d\n",ans); } return 0; }
H题。。。看pdf蛋疼,先不补了。
I - Disks
那些对向右扩展没有贡献的圆就是答案了。#include <cstdio> #include <cmath> #include <cstring> #define F(_i,_u) for(int _i=0;_i<(_u);_i++) #define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++) #define FS(_i,_r,_l) for(int _i=_r;_i>=(_l);_i--) using namespace std; double R[1005],Local[1005]; int anss[1005],adj[1005]={0}; int main(){ memset(adj,-1,sizeof(adj)); int n,ans=0,ar=0;double r=0,dis,r2,r1; Local[0]=R[0]=0; scanf("%d",&n); FF(i,1,n)scanf("%lf",&R[i]); FF(i,1,n){ Local[i]=R[i]; FF(j,1,i-1){ r1=R[j];r2=R[i];if(r1<r2)r1=R[i],r2=R[j]; dis=sqrt((r1+r2)*(r1+r2)-(r1-r2)*(r1-r2))+Local[j]; if(Local[i]<dis){ Local[i]=dis; adj[i]=j; } } if(r<Local[i]+R[i])r=Local[ar=i]+R[i]; } for(int i=n;i>ar;i--)anss[ans++]=i; for(int i=ar;i>0;i=adj[i]){ ar=i-1; while(ar>0&&ar>adj[i])anss[ans++]=ar--; } printf("%d\n",ans); for(int i=ans-1;i+1;i--)printf("%d\n",anss[i]); }
相关文章推荐
- 2018 BUPT Winter Training #7 Div.2
- 2018 BUPT Winter Training #8 Div.2
- 2018 BUPT Winter Training #1 div.2
- 2018 BUPT Winter Training #2 Div.2
- 2018 BUPT Winter Training #3 Div.2
- 2018 BUPT Winter Training #4 Div.2
- 2018 BUPT Winter Training #5 Div.2
- codeforces hellow 2018 div.2
- 2018 BUPT Winter Training #1 div.1
- 2017-2018-1 20155230 mypwd实现
- 20162329 2017-2018-1 《程序设计与数据结构》第十一周学习总结
- 04/08/2018 笔记
- 2017-2018-1 20155218 《信息安全系统设计基础》第九周学习总结
- BlackHat Arsenal USA 2018 ToolsWatch黑客工具库
- 网易2018校招内推编程题集合:交错01串 [python]
- 2018web前端不好找工作之web前端面试简历补救篇
- HDU - 2018母牛的故事 - 递推
- 【Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) C】
- 企服三会·PPT | 中国软件网曹开彬:洞见2018中国移动办公趋势洞察报告