double qiuzhi(int id) { double t1=cc[id].rid*cc[id].rid; double t2=w*w/4; double t3=t1-t2; double t4=sqrt(t3); return t4; } void to_qujian() { for(int i=0; i<t; i++) { double zhi=qiuzhi(i); qq[i].a=cc[i].pos-zhi; qq[i].b=cc[i].pos+zhi; } }
对本题来说,关键的一点在于由具体问题向“区间”的抽象~!用圆与矩形边的交点作为区间的左右端点!
用了两种方法,按书上的方法,采取多次截取合适区间的方法做了一遍,代码比较清晰实现出来了,但是超时。
原因已经分析清楚,本以为是0(n)的复杂度,但是忽略了排序的n log(n)的复杂度,每次循环都排序,10000的数据量超时是意料之中的事情。
#include<cstdio>//这是超时的代码~看清楚了~~ #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> using namespace std; const int maxn=10000+10; int n,t; double l,w; int flag1,flag2; struct circle { double pos; double rid; } cc[maxn]; struct qujian { double a; double b; } qq[maxn]; void input(int n,double l,double w) { t=0; int temp=n; for(int i=0; i<temp; i++) { double a1,b1; scanf("%lf%lf",&a1,&b1); if(b1<=w/2) { n--; continue; } else { cc[t].pos=a1; cc[t++].rid=b1; } } } bool cut_qujian(double left,double right) { flag1=0; flag2=0; for(int i=0; i<t; i++) { if(qq[i].a<=left) { flag1=1; qq[i].a=left; } if(qq[i].b>=right-0.0000000001) { flag2=1; qq[i].b=right; } } if(flag1==1&&flag2==1) return true; else return false; } double qiuzhi(int id) { double t1=cc[id].rid*cc[id].rid; double t2=w*w/4; double t3=t1-t2; double t4=sqrt(t3); return t4; } void to_qujian() { for(int i=0; i<t; i++) { double zhi=qiuzhi(i); qq[i].a=cc[i].pos-zhi; qq[i].b=cc[i].pos+zhi; } } int cmp(qujian a,qujian b) { if(a.a!=b.a) return a.a<b.a; else return a.b>b.b; } int main() { while(scanf("%d%lf%lf",&n,&l,&w)!=EOF) { input(n,l,w); to_qujian(); double left=0,right=l; int ans=-1; int cnt=0; while(cut_qujian(left,right)) { cnt++; sort(qq,qq+t,cmp); left=qq[0].b; if(left>=right) { ans=1; break; } } if(ans==-1) { printf("-1\n"); } else printf("%d\n",cnt); } return 0; }
然后思路肯定是不能换,就换实现的方式好了~
用了下面这种看似0(n^2),但实际上复杂度为0(n)的方法,学长给的,觉得很好。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<cstdlib> using namespace std; const int maxn=10000+10; int n,t; double l,w; int flag1,flag2; struct circle { double pos; double rid; } cc[maxn]; struct qujian { double a; double b; } qq[maxn]; void input(int n,double l,double w) { t=0; int temp=n; for(int i=0; i<temp; i++) { double a1,b1; scanf("%lf%lf",&a1,&b1); if(b1<=w/2) { n--; continue; } else { cc[t].pos=a1; cc[t++].rid=b1; } } } double qiuzhi(int id) { double t1=cc[id].rid*cc[id].rid; double t2=w*w/4; double t3=t1-t2; double t4=sqrt(t3); return t4; } void to_qujian() { for(int i=0; i<t; i++) { double zhi=qiuzhi(i); qq[i].a=cc[i].pos-zhi; qq[i].b=cc[i].pos+zhi; } } int cmp(qujian a,qujian b) { return a.a<b.a; } int solve() { int cnt=0; double right=0; for(int i=0; i<t; i++) { double nowr=right; for(; qq[i].a<=right; i++) { if(qq[i].b>nowr) nowr=qq[i].b; } if(nowr==right) return -1; right=nowr; cnt++; i--; } if(right<l) return -1; return cnt; } int main() { while(scanf("%d%lf%lf",&n,&l,&w)!=EOF) { input(n,l,w); to_qujian(); int ans; sort(qq,qq+t,cmp); ans=solve(); if(ans==-1) { printf("-1\n"); } else printf("%d\n",ans); } return 0; }