数值方法专题

数值方法

UVA 10341

解方程: pex+rcos(x)+stan(x)+tx2+u=0,0x1

二分

#include<iostream>
#include<cmath>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define F(x) ((double)p*exp(-(x))+q*sin(x)+r*cos(x)+s*tan(x)+t*(x)*(x)+u)
#define eps (1e-6)
int main()
{
//  freopen("uva10341.in","r",stdin);
//  freopen(".out","w",stdout);

    double p,q,r,s,t,u;
    while(cin>>p>>q>>r>>s>>t>>u) {
        double f0=F(0),f1=F(1);
        if (f0<-eps || f1>eps) puts("No solution");
        else {
            double L=0,R=1;
            For(i,100) {
                double m=(R+L)/2;
                if (F(m) > 0) L=m;
                else R=m;
            }
            printf("%.4lf\n",R);
        }
    }


    return 0;
}

LA 5009 Error Curves

题意:已知n条二次曲线 Si(x)=aix2+bix+c(ai0) ,定义 F(x)=max(Si(x)) ,求F(x)在[0,1000]上的最小值

三分

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (10000+10)
int n,a[MAXN],b[MAXN],c[MAXN];
double f(double x) {
    double ans=a[1]*x*x+b[1]*x+c[1];
    For(i,n) ans=max(ans,a[i]*x*x+b[i]*x+c[i]);
    return ans;
}
int main()
{
//  freopen("la5009.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    while(T--) {
        n=read();
        For(i,n) a[i]=read(),b[i]=read(),c[i]=read();
        double L=0,R=1000;
        For(i,100) {
            double m1=L+(R-L)/3;
            double m2=R-(R-L)/3;
            if (f(m1)<f(m2)) R=m2; else L=m1;
        }
        printf("%.4lf\n",f(L));
    }   
    return 0;
}

LA 3485 Bridge

题意:有一座桥,桥上等距摆着高为H的塔,塔宽忽略不计,两塔间距离不超过D,塔之间的绳索形成全等对称的抛物线,桥长为B,绳索总长L,求建最少的塔时绳索最下端到地面的距离y

算定积分+二分

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
double F(double a,double x) {
    double a2=a*a,x2=x*x;
    double t=sqrt(a2+x2);
    return x*t/2+a2*log(fabs(x+t))/2;
}
double parabola_arc_l(double w,double h) {
    double a=4*h/w/w;
    return 4*a*(F(1/(2*a),w/2)-F(1/(2*a),0));
}
int main()
{
//  freopen("la3485.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    double D,H,B,L;
    int kcase=1;
    while(cin>>D>>H>>B>>L) {
        if (kcase>1) puts("");
        printf("Case %d:\n",kcase++);

        double n = ceil(B/D);
        double w = B/n;
        double l=0,r=H;
        For(i,100) {
            double m=(l+r)/2;
            if (parabola_arc_l(w,m)< L/n ) l=m; else r=m; 
        }
        printf("%.2lf\n",H-l);


    }

    return 0;
}

算Simpson积分

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 

namespace Simpson{
    double a;
    double f(double x) {
        return sqrt(1+4*a*a*x*x);
    }
    double simpson(double a,double b) {
        double c=(a+b)/2;
        return (f(a)+f(b)+4*f(c)) * (b-a) / 6;
    }
    double asr(double a,double b,double eps,double A) {
        double c=(a+b)/2;
        double l=simpson(a,c),r=simpson(c,b);

        if (fabs(l+r-A)<=15*eps) return l+r+(l+r-A)/15.;
        return asr(a,c,eps/2,l)+asr(c,b,eps/2,r);
    }
    double asr(double a,double b,double eps) {
        return asr(a,b,eps,simpson(a,b));
    }
}

double parabola_arc_l(double w,double h) {
    Simpson::a=4*h/w/w;
    return 2*Simpson::asr(0,w/2,1e-5);
}
int main()
{
//  freopen("la3485.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    double D,H,B,L;
    int kcase=1;
    while(cin>>D>>H>>B>>L) {
        if (kcase>1) puts("");
        printf("Case %d:\n",kcase++);

        double n = ceil(B/D);
        double w = B/n;
        double l=0,r=H;
        For(i,100) {
            double m=(l+r)/2;
            if (parabola_arc_l(w,m)< L/n ) l=m; else r=m; 
        }
        printf("%.2lf\n",H-l);


    }

    return 0;
}

UVA 10668 Expanding Rods

提议:一根木棒长度从L变为(1+nC)L,把木棒两端固定,使其变为圆弧行,问木棍中心的位移?
L,n,C 已知

二分,注意精度

#include<bits/stdc++.h>
#include<cmath>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
double L,n,C;
double f(double x) {
    return sin(x/2)-x/2/(1+n*C);
}
int main()
{
//  freopen("uva10668.in","r",stdin);
//  freopen(".out","w",stdout);

    while(cin>>L>>n>>C) {
        if (L<0 && n<0 && C<0) return 0;
        double l=0,r= L / 2 ;
        double L2 = (1+n*C)*L;
        For(i,1000) {
            double m=(l+r)/2;
            double R=(L * L /4 + m*m )/2/m;
            double S=2*R*atan(L/2/(R-m));                       
            if (S>L2) r=m; else l=m;
`
` 


}       


        printf("%.3lf\n",l);

    }   
    return 0;
}

UVA 10385 Duathlon

题意:在[0,t]内,有若干条直线的 yi ,现在希望找到 max(yn(x)min(y1(x),y2(x),,yn1(x))) , 并求出此时的x

显然 y=min(y1(x),y2(x),,yn1(x)) 是单峰的( y(x) 单调非增)
yn(x) 常数,所以 z=yn(x)min(y1(x),y2(x),,yn1(x)) 是单峰的

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (100000+10) 
double t;
int n;
double v1[MAXN],v2[MAXN];
double calc(double r) { //别人的时间 - 我的时间   
    double ans=INF;
    For(i,n-1) ans=min(ans, r / v1[i] + (t-r)/v2[i] );
    return ans - ( r/v1[n] + (t-r)/v2[n] ) ;
}
int main()
{
//  freopen("uva10385.in","r",stdin);
//  freopen(".out","w",stdout);

    while(cin>>t>>n){
        For(i,n) {
            cin>>v1[i]>>v2[i];
        }

        double l=0,r=t;
        For(i,1000) {
            double l1 = l + (r-l)/3;
            double r1 = r - (r-l)/3;
            if (l1 < r1 ){ 
                if (calc(l1) < calc(r1) ) l = l1;
                else r = r1;
            } 
        }
        double ans=calc(l)*3600;
        if (ans<0) puts("The cheater cannot win."); 
        else printf("The cheater can win by %.lf seconds with r = %.2lfkm and k = %.2lfkm.\n",ans,l,t-l);
    }


    return 0;
}

题意:给两圆柱求正交
这里写图片描述

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
                        For(j,m-1) cout<<a[i][j]<<' ';\
                        cout<<a[i][m]<<endl; \
                        } 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
double r,h;
#define pi (3.14159265358579) 
namespace Simpson{
    double f(double x) {
        double l=sqrt(r*r-(r-x)*(r-x));
        return 2*l*h+2*asin((r-x)/r)*r*r-2*l*(r-x);
    } 
    double simpson(double a,double b) {
        double c=(a+b)/2;
        return (f(a)+f(b)+4*f(c)) * (b-a) / 6;
    }
    double asr(double a,double b,double eps,double A) {
        double c=(a+b)/2;
        double l=simpson(a,c),r=simpson(c,b);

        if (fabs(l+r-A)<=15*eps) return l+r+(l+r-A)/15.;
        return asr(a,c,eps/2,l)+asr(c,b,eps/2,r);
    }
    double asr(double a,double b,double eps) {
        return asr(a,b,eps,simpson(a,b));
    }
}
namespace Simpson2{
    double f(double x) {
        double S1 = x* sqrt(r*r-x*x)/2;
        double S2 = h/4*sqrt(r*r-h*h/4);
        double S3 = abs(asin(x/r)-asin(h/2/r))/2*r*r;
        return S1+S2+S3;
    } 
    double simpson(double a,double b) {
        double c=(a+b)/2;
        return (f(a)+f(b)+4*f(c)) * (b-a) / 6;
    }
    double asr(double a,double b,double eps,double A) {
        double c=(a+b)/2;
        double l=simpson(a,c),r=simpson(c,b);

        if (fabs(l+r-A)<=15*eps) return l+r+(l+r-A)/15.;
        return asr(a,c,eps/2,l)+asr(c,b,eps/2,r);
    }
    double asr(double a,double b,double eps) {
        return asr(a,b,eps,simpson(a,b));
    }
}
int main()
{
//  freopen("uva5096.in","r",stdin);
//  freopen(".out","w",stdout);

    while(cin>>r>>h) {
        if (r<h/2) {
            printf("%.4lf\n",pi*r*r*(h-2*r)+2*Simpson::asr(0,r,1e-7));
        } else {
            double v = Simpson2::asr(0,h/2,1e-7)*8;

            printf("%.4lf\n",pi*r*r*h+pi*r*r*h-v);
        }
    }


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值