• NOIP模拟4


    期望得分:20+100+100=220

    实际得分:20+100+100=220

    特判相离、内含

    对于两圆相交的情况,一直在考虑求交点

    实际上相交的面积可以用两个扇形减去两个三角形

    正弦定理、余弦定理来搞搞

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const double pi=acos(-1.0);
    const double eps=1e-6;
    double Two_point_dis(double x1,double yy1,double x2,double yy2)
    {
        return sqrt((x1-x2)*(x1-x2)+(yy1-yy2)*(yy1-yy2));
    }
    double circle_S(double r)
    {
        return pi*r*r;
    }
    int main()
    {
        freopen("standing.in","r",stdin);
        freopen("standing.ans","w",stdout);
        int T;
        scanf("%d",&T);
        double x1,yy1,r1,x2,yy2,r2;
        while(T--)
        {
            scanf("%lf%lf%lf%lf%lf%lf",&x1,&yy1,&r1,&x2,&yy2,&r2);
            double dis=Two_point_dis(x1,yy1,x2,yy2);
            if(dis>=r1+r2)
            {
                printf("%.3lf
    ",circle_S(r1)+circle_S(r2));
                continue;
            }
            if(dis<=fabs(r1-r2))
            {
                printf("%.3lf
    ",max(circle_S(r1),circle_S(r2)));
                continue;
            }
            else 
            {
                double ans=circle_S(r1)+circle_S(r2);
                double j1=acos((r1*r1+dis*dis-r2*r2)/(2*r1*dis));
                double l1=j1*2*r1;
                double j2=acos((r2*r2+dis*dis-r1*r1)/(2*r2*dis));
                double l2=j2*2*r2;
                double s1=l1*r1*0.5;
                double s2=l2*r2*0.5;
                double s=r1*dis*sin(j1);
                ans-=(s1+s2-s);
                printf("%.3lf
    ",ans);
            }
        }
    }
    View Code

    约瑟夫环问题

    公式推导:http://blog.csdn.net/u011500062/article/details/72855826?locationNum=6&fps=1

    #include<cstdio>
    using namespace std;
    int main()
    {
        freopen("resist.in","r",stdin);
        freopen("resist.out","w",stdout);
        int n,k,ans=0;
        scanf("%d%d",&n,&k);
        for(int i=2;i<=n;i++)
         ans=(ans+k)%i;
        printf("%d",ans+1);
    }
    View Code

    贪心

    最大值:

    什么视图要求为x,就把对应的位置全弄成x

    所以最后每个位置的高度为min(left[j],front[i])

    最小值:

    先看主视图

    如果主视图i=左视图j,且之前第j列没有高度能满足左视图j,那么(i,j)的高度就是主视图i

    否则,任选一个左视图j>=主视图i的j,(i,j)的高度为主视图i

    再看左视图

    j已经被满足,忽略

    否则,任选一个主视图i<=左视图j的i,(i,j)的高度为左视图j

    #include<cstdio>
    #include<iostream>
    #define N 1011
    using namespace std;
    int n,m;
    int front[N],leftt[N];
    int maxn[N][N],minn[N][N];
    int sumd,sumx;
    bool have[N];
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar();}
    }
    int main()
    {
        freopen("neighbor.in","r",stdin);
        freopen("neighbor.out","w",stdout);
        read(n); read(m);
        for(int i=1;i<=n;i++) read(front[i]);
        for(int i=m;i;i--) read(leftt[i]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                maxn[i][j]=front[i];
        for(int j=1;j<=m;j++)
            for(int i=1;i<=n;i++)
                maxn[i][j]=min(maxn[i][j],leftt[j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                sumd+=maxn[i][j];
                
        bool ok;        
        for(int i=1;i<=n;i++)
        {
            ok=false;
            for(int j=1;j<=m;j++)
            {
                if(have[j]) continue;
                if(leftt[j]==front[i]) { minn[i][j]=front[i]; have[j]=ok=true; break; }
            }
            if(ok) continue;
            for(int j=1;j<=m;j++)
                if(leftt[j]>=front[i]) { minn[i][j]=front[i]; break; }
        }
        for(int j=1;j<=m;j++)
        {
            ok=false;
            for(int i=1;i<=n;i++)
                if(minn[i][j]==leftt[j]) { ok=true; break; }
            if(ok) continue;
            for(int i=1;i<=n;i++)
                if(minn[i-1][j]==leftt[j]) { minn[i-1][j]=0; minn[i][j]=leftt[j]; ok=true; break; }
            if(ok) continue;
            for(int i=1;i<=n;i++)
                if(leftt[j]<=front[i]) { minn[i][j]=leftt[j]; break; }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                sumx+=minn[i][j];
        printf("%d %d",sumx,sumd);
    }
    View Code
  • 相关阅读:
    吴裕雄--天生自然C++语言学习笔记:C++ 标准库
    吴裕雄--天生自然C++语言学习笔记:C++ STL 教程
    吴裕雄--天生自然C++语言学习笔记:C++ Web 编程
    吴裕雄--天生自然C++语言学习笔记:C++ 多线程
    吴裕雄--天生自然C++语言学习笔记:C++ 信号处理
    吴裕雄--天生自然C++语言学习笔记:C++ 预处理器
    吴裕雄--天生自然C++语言学习笔记:C++ 模板
    吴裕雄--天生自然C++语言学习笔记:C++ 命名空间
    ZOJ1905Power Strings (KMP||后缀数组+RMQ求循环节)
    POJ3693Maximum repetition substring (循环节)(后缀数组+RMQ)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7497740.html
Copyright © 2020-2023  润新知