A - Light Bulb:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3203
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
double H,h,D;
double f(double x)
{
return D*(h-x)/(H-x)+x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf",&H,&h,&D);
double dl,dr,l=0,r=h,lmid,rmid;
while(r-l>1e-8)
{
lmid=l+(r-l)/3.0;
rmid=r-(r-l)/3.0;
dl=f(lmid);
dr=f(rmid);
if(dl<dr) l=lmid;
else r=rmid;
}
printf("%.3lf\n",dl);
}
return 0;
}
B - Turn the corner (HDU2438)
判断汽车能否过弯,这题做了好半天,简直就是数学题啊!(画图好麻烦,还这么丑!)
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define cot(a) (cos(a)/sin(a))
#define INF 0x7fffffff
using namespace std;
double x,y,L,d;
const double PI=acos(-1.0);
double f(double a)
{
double S=y+x*cot(a);
return (S*sin(a)-d)/(sin(a)*cos(a));
}
int main()
{
while(scanf("%lf%lf%lf%lf",&x,&y,&L,&d)!=EOF)
{
double dl,dr,l=0,r=PI/2,lmid,rmid;
for(int i=0;i<100;i++)
{
lmid=l+(r-l)/3.0;
rmid=r-(r-l)/3.0;
dl=f(lmid);
dr=f(rmid);
if(dl>dr)
l=lmid;
else r=rmid;
}
if(dl>L) cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
return 0;
}
C - The Moving Points (HDU 4717)
给n个点,每个点有个速度,求所有点的最大距离最小的时刻。
一开始读错题了! 以为求最小距离最小的时刻。 ==! Wrong了8次!!!
还是三分,每次判断所有点的最远距离。
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
int n;
struct point
{
double x,y,vx,vy;
}p[400];
double dis(double t,int a,int b)
{
double ax=p[a].x+t*p[a].vx;
double bx=p[b].x+t*p[b].vx;
double ay=p[a].y+t*p[a].vy;
double by=p[b].y+t*p[b].vy;
return (ax-bx)*(ax-bx)+(ay-by)*(ay-by);
}
double check(double x)
{
double ans=0;
int i,j;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
ans=max(dis(x,i,j),ans);
return ans;
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].vx,&p[i].vy);
double l=0,r=1e8,lmid,rmid,d=0;
while(r-l>1e-8)
{
lmid=l+(r-l)/3.0;
rmid=r-(r-l)/3.0;
d=check(lmid);
if(d>check(rmid))
l=lmid;
else r=rmid;
}
printf("Case #%d: %.2lf %.2lf\n",cas++,r,sqrt(d));
}
return 0;
}
D - Solve this equation HDU 2199
给你个函数,求零点,裸的二分。
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
double Y;
double f(double x)
{
return 8.0*x*x*x*x + 7.0*x*x*x + 2.0*x*x + 3.0*x + 6 - Y ;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lf",&Y);
if(f(0)*f(100)>0)
{
printf("No solution!\n");
continue;
}
double l=0,r=100,mid;
for(int i=0; i<100; i++)
{
mid=(l+r)/2;
if(f(mid)<0) l=mid;
else r=mid;
}
printf("%.4lf\n",l);
}
return 0;
}
E - UmBasketella POJ 3737
给你圆锥的表面积,求最大体积。
也是三分,用 g++交Wrong了三次,换c++就A了
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
double S,L,h;
const double PI=acos(-1.0);
long double f(long double r)
{
L=S-(PI*r*r);
L/=PI*r;
h=sqrt(L*L-r*r);
return PI*r*r*h/3;
}
int main()
{
while(scanf("%lf",&S)!=EOF)
{
double dl,dr,l=0,r=S,lmid,rmid;
for(int i=0;i<100;i++)
{
lmid=l+(r-l)/3.0;
rmid=r-(r-l)/3.0;
dl=f(lmid);
dr=f(rmid);
if(dl<dr)
l=lmid;
else r=rmid;
}
printf("%.2lf\n%.2lf\n%.2lf\n",dl,h,l);
}
return 0;
}
F - Party All the Time HDU 4355
刚开始看了半天没看懂什么意思。
就是说有n个小精灵,他们走过一段距离就有个不开心指数,问聚集所有小精灵所达到的最小不开心指数之和是多少。
还是极值问题,要求四舍五入化成整数。直接%.0lf好像就行了。
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
double x[100005];
double w[100005];
int n;
double f(double p)
{
double sum=0;
for(int i=0;i<n;i++)
{
double s=fabs(p-x[i]);
sum+=s*s*s*w[i];
}
return sum;
}
int main()
{
int T,i,C=0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
double Max=0;
for(i=0;i<n;i++)
{
scanf("%lf%lf",&x[i],&w[i]);
Max=max(Max,x[i]);
}
double l=0,r=Max,m1,m2;
while(r-l>1e-4)
{
m1=l+(r-l)/3;
m2=r-(r-l)/3;
if(f(m1)>f(m2)) l=m1;
else r=m2;
}
printf("Case #%d: %.0lf\n",++C,f(m1));
}
return 0;
}
G - Line belt HDU 3400
给你两个线段AB和CD,在AB上的速度为P,CD上的速度为Q,其他部分为R,求A到D的最小时间。
三分套三分。第一次三分枚举AB上的点,然后第二次枚举CD上的点,然后算出总时间作为比较值。
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#define INF 0x7fffffff
using namespace std;
struct point
{
double x,y;
}a,b,c,d;
double v1,v2,v0;
double ax,ay,bx,by,cx,cy,dx,dy;
double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double f(point x)
{
double t1,t2;
point l,r,m1,m2;
l=c,r=d;
for(int i=0;i<100;i++)
{
m1.x=(l.x+r.x)/2;
m1.y=(l.y+r.y)/2;
m2.x=(m1.x+r.x)/2;
m2.y=(m1.y+r.y)/2;
t1=dis(m1,x)/v0+dis(m1,d)/v2;
t2=dis(m2,x)/v0+dis(m2,d)/v2;
if(t1>t2) l=m1;
else r=m2;
}
return t1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y;
cin>>v1>>v2>>v0;
point l,r,m1,m2;
double t1,t2;
l=a;r=b;
for(int i=0;i<100;i++)
{
m1.x=(l.x+r.x)/2;
m1.y=(l.y+r.y)/2;
m2.x=(m1.x+r.x)/2;
m2.y=(m1.y+r.y)/2;
t1=dis(m1,a)/v1+f(m1);
t2=dis(m2,a)/v1+f(m2);
if(t1>t2) l=m1;
else r=m2;
}
printf("%.2lf\n",t2);
}
return 0;
}
H - The Frog's Games HDU 4004
经典的最大值最小化问题。
二分枚举最小值,判断是否可行。
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#define INF 0x7fffffff
using namespace std;
int a[1000004];
int main()
{
int n,m,T,L,i;
while(scanf("%d%d%d",&L,&n,&m)!=EOF)
{
int mx=0;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
mx=max(mx,a[i]);
}
sort(a,a+n);
int mn=0;
for(i=n-1;i>0;i--)
a[i]-=a[i-1];
a[n++]=L-mx;
for(i=0;i<n;i++)
mn=max(mn,a[i]);
int mid=0,l=mn,r=L;
while(l<r)
{
mid=(l+r)/2;
int cnt=0,sum=0;
for(i=0;i<n;i++)
{
if(sum+a[i]<=mid) sum+=a[i];
else sum=a[i],cnt++;
}
if(sum>0) cnt++;
if(cnt<=m) r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}