09-04 HDU_Steps4.1 二分三分 HDU2199 HDU2899 HDU1967 HDU2141 HDU2298 HDU1597 HDU2438 HDU3400

來源:互聯網
上載者:User

Steps 4.1主要都是二分和三分的問題,二分這種思想很重要也很常用.另外,在浮點數運算時一定要注意精度問題.


4.1.1 HDU 2199 Can you solve this equation

函數單調遞增,當f(0)>0或者f(100)<0時無解,二分答案即可,精度要到1e-6


4.1.2 HDU2899 Strange Function

凸函數,三分法可以做.我是先求導,它的導數是單調的,所以求出導數=0時的x,再代入原式就可以了


4.1.3 HDU1967 Pie 

問每個人最多可以分多大的Pie,先對面積進行排序,然後在0和最大的Pie面積之間二分求答案,對每一個值計算是否可以達到F+1塊,當然,優先去切大塊的Pie...另外需要注意的是,計算圓形面積時 PI=acos(-1) 直接寫3.141592653會有精度問題


4.1.4 HDU2141 Can You Find it

二分尋找,先計算出所有a+b的結果儲存並排序,然後對k,去二分尋找k-c (a+b=k-c) 500MS+

當然,更好的方法是用Hash表,尋找複雜度O(1),這題就當練一下二分尋找了..

#include <cstdio>#include <algorithm>using namespace std;typedef __int64 LL;const int maxn=505;LL a[maxn],b[maxn],c[maxn],ab[maxn*maxn];int cas=1,n,m,l,ks,k,low,high,mid;bool findk(int x){low=0,high=l*n;while(high-low>1){int mid=(high+low)/2;if(ab[mid]==x)return true;if(ab[mid]>x)high=mid;else low=mid;}return false;}int main(){while(scanf("%d%d%d",&l,&n,&m)!=EOF){for(int i=0;i<l;i++)scanf("%I64d",&a[i]);for(int i=0;i<n;i++)scanf("%I64d",&b[i]);for(int i=0;i<m;i++)scanf("%I64d",&c[i]);//儲存a+b的結果並排序 for(int i=0;i<l;i++)for(int j=0;j<n;j++)ab[i*n+j]=a[i]+b[j];sort(ab,ab+l*n);printf("Case %d:\n",cas++);scanf("%d",&ks);while(ks--){scanf("%d",&k);int find=0;//在[a+b]中尋找有沒有等於c-k的值 for(int i=0;i<m;i++){if(findk(k-c[i])){find=1;break;}}printf(find?"YES\n":"NO\n");}}}

4.1.5 HDU2298 Toxophily

直接當數學題做了(物理題?..)正交分解然後消去y變成一元二次方程,解這個方程就可以了.注意幾點問題,delta<0時無解,在x==0時,方程不是一元二次方程,這時如果在原點就可直接到達,如果在y軸上則垂直上射,另外座標在第一象限,解為正數,要選取較小的正數解..

這題雖說簡單..想輕鬆A還是不太容易的....

#include <cstdio>#include <cmath> using namespace std;const double g=9.8;int cas;double x,y,v,a,b,c,ans1,ans2,delta;int main(){scanf("%d",&cas);while(cas--){scanf("%lf%lf%lf",&x,&y,&v);//注意判斷,x==0時,方程不是一元二次方程 if(x==0){if(y==0)printf("0.000000\n");if(y>0)printf("%.6lf\n",acos(-1)/2);continue;}//轉化為一元二次方程,未知數是tan(alpha); a=g*x*x;b=-x*2*v*v;c=2*y*v*v+g*x*x;delta=b*b-4*a*c;//delta<0無解 if(delta<0)printf("-1\n");else{//選取較小的正解(x>=0,y>=0,tan(alpha)>=0) ans1=(-b-sqrt(b*b-4*a*c))/2/a;ans2=(-b+sqrt(b*b-4*a*c))/2/a;if(ans2<0)printf("-1\n");else if(ans1<0)printf("%.6lf\n",atan(ans2));else printf("%.6lf\n",atan(ans1));}}return 0;}

4.1.6 HDU1597 Find the nth digit

水題一道,注意資料溢出問題


4.1.7 HDU2438 Turn The Corner

沒有良好的數學功底真的很難做出這題,先要建系


然後列出小車上邊一條邊的方程,然後求這個方程和y=X的交點的最大值,很明顯是個凸函數,用三分法解...不知道為什麼,一開始用二分left,right,在二分mid和right的三分做一直WA,後來改成平均三分就A了..理論上來說應該都沒問題啊..

#include <cstdio>#include <cmath>using namespace std;double x,y,l,d,mid,midmid,low,high;double cal(double jd){return (l*sin(jd)+d/cos(jd)-x)/tan(jd); }int main(){/*以右下角為原點建立座標系,Y=Xtan(a)+l*sin(a)+d/cos(a)再將Y=x代入,求X關於角度a的最大值(0<=a<=PI/2); */ while(~scanf("%lf%lf%lf%lf",&x,&y,&l,&d)){high=acos(-1.0)/2.0,low=0.0;//三分法求極值 while(high-low>1e-4){mid=(high-low)*1.0/3.0+low;midmid=(high-low)*2.0/3.0+low;if(cal(mid)>cal(midmid))high=midmid;else low=mid;}printf(y-cal(low)>0?"yes\n":"no\n");}return 0;}



4.1.8 HDU3400 Line belt

一道三分的好題,嵌套三分求解..不看大牛的文章真想不到這題是用三分法做的..

這篇文章解釋的比較詳細http://hi.baidu.com/myzone2009/blog/item/1f9560ccdf5d045d0eb34535.html

我是以T為自變數的,這樣有一個小問題,求不線上段上走的距離時會除距離,既然有除法就要注意除0問題,所以在求距離時要加上一個小精度..否則就會WA..

#include <cstdio>#include <cmath>#include <cstdlib>using namespace std;/*F(X)=G(X)+H(Y)G(X)單調,H(Y)是凸函數,則F(X)也是凸函數其中G(X)是在AB上的時間,H(Y)是在CD上的時間加上飛機上的時間 */double ax,ay,bx,by,cx,cy,dx,dy,p,q,r;double l1,l2,h1,h2,m11,m12,m21,m22;double dis(double x1,double y1,double x2,double y2){return sqrt(1e-6+(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}double cal(double m1,double m2){double x1,x2,y1,y2;x1=ax+m1*p*(bx-ax)/dis(ax,ay,bx,by);y1=ay+m1*p*(by-ay)/dis(ax,ay,bx,by);x2=dx+m2*q*(cx-dx)/dis(cx,cy,dx,dy);y2=dy+m2*q*(cy-dy)/dis(cx,cy,dx,dy);return dis(x1,y1,x2,y2)/r;}double calsf(double m){l2=0,h2=dis(cx,cy,dx,dy)/q;while(h2-l2>1e-6){m21=(h2-l2)*1.0/3.0+l2;m22=(h2-l2)*2.0/3.0+l2;if(m21+cal(m,m21)<m22+cal(m,m22))h2=m22;else l2=m21;}return h2+cal(m,h2);}int main(){int cas;scanf("%d",&cas);while(cas--){scanf("%lf%lf%lf%lf",&ax,&ay,&bx,&by);scanf("%lf%lf%lf%lf",&cx,&cy,&dx,&dy);scanf("%lf%lf%lf",&p,&q,&r);l1=0,h1=dis(ax,ay,bx,by)/p;while(h1-l1>1e-6){m11=(h1-l1)*1.0/3.0+l1;m12=(h1-l1)*2.0/3.0+l1;if(m11+calsf(m11)<m12+calsf(m12))h1=m12;else l1=m11;}printf("%.2lf\n",h1+calsf(h1));}return 0;} 


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.