9.9 NOIP模拟题

9.9 NOIP模拟题

T1 两个圆的面积求并

/*
计算圆的面积并
多个圆要用辛普森积分解决
这里只有两个,模拟计算就好
两圆相交时,面积并等于中间两个扇形面积减去两个三角形面积
余弦定理求角度,算出三角形面积 
*/
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double PI=3.14159265358979323846264; 
struct node{
    double x,y;
    double r;
}a[2];
inline double getdis(node b,node c){
    double xx=b.x-c.x;
    double yy=b.y-c.y;
    return sqrt(xx*xx+yy*yy);
}

void deal(node b,node c)
{
    double len=getdis(b,c);
    if(len<=fabs(b.r-c.r)){
        if(b.r<c.r) swap(b,c);
        double t1=PI*b.r*b.r;
        printf("%.3lf
",t1);
        return ;
    }
    double L=b.r+c.r;
    double t1=PI*b.r*b.r;
    double t2=PI*c.r*c.r;
    if(L<=len){
        printf("%.3lf
",t1+t2);
        return ;
    }
    double ang1=acos((b.r*b.r+len*len-c.r*c.r)/2.0/b.r/len);  
    double ang2=acos((c.r*c.r+len*len-b.r*b.r)/2.0/c.r/len);
    double ret=ang1*b.r*b.r+ang2*c.r*c.r-len*b.r*sin(ang1);   
    printf("%.3lf
",t1+t2-ret);
}

int main()
{
    freopen("standing.in","r",stdin);
    freopen("standing.out","w",stdout);
    int T;scanf("%d",&T);
    while(T--){
        scanf("%lf%lf%lf%lf%lf%lf",&a[0].x,&a[0].y,&a[0].r,&a[1].x,&a[1].y,&a[1].r);
        deal(a[0],a[1]);
    }
    return 0;
}

T2 约瑟夫问题

/*
其实也就是建好线段树
然后查找第m+1个数的位置,然后把这个位置到根的路径都-1.
*/
#include<cstdio>
#include <iostream>
#define N 100007

using namespace std;
struct SegTree
{
    int l,r,m;
    int num;
};
SegTree ltree[N<<2];
int n,m,ln;int ans[N];

void init(int nowat, int tl, int tr)
{
    ltree[nowat].l=tl;
    ltree[nowat].r=tr;
    ltree[nowat].m=(tl+tr)>>1;
    ltree[nowat].num=tr-tl+1;
    if(tl<tr)
    {
        init(nowat*2,tl,ltree[nowat].m);
        init(nowat*2+1,ltree[nowat].m+1,tr);
    }
}

void del(int nowat, int tw)
{
    --ltree[nowat].num;
    if (ltree[nowat].l<ltree[nowat].r)
    {
        if (tw<=ltree[nowat].m) del(nowat*2,tw);
        else del(nowat*2+1,tw);
    }
}

int findcode(int tcode)
{
    int i=1;
    int sum=0;
    while (ltree[i].l<ltree[i].r)
    {
        if(sum+ltree[i+i].num<tcode)
        {
            sum+=ltree[i+i].num;
            i=i+i+1;
        }
        else i=i+i;
    }
    return ltree[i].r;
}

int main()
{
    freopen("resist.in","r",stdin);
    freopen("resist.out","w",stdout);
    scanf("%d%d",&n,&m);
    ln=0;init(1,1,n);
    int i,j,k=0;int num=0;
    for (i=1;i<=n;++i)
    {
        k=(k+m-1)%(n-i+1);
        j=findcode(k+1);ans[++num]=j;
        del(1, j);
        if (i!=n)k=k%(n-i);
    }
    printf("%d
",ans[num]);
    fclose(stdin);fclose(stdout);
    return 0;
}

T3 给你矩阵的正视图和左视图中每个点的值   让你求俯视图和的范围

/*
最大值好求 
最小值就是行和列出现同一个数后
那个出现次数多的出现的次数乘上这个数 
*/
#include<iostream>
#include<cstdio>
#include<cstring>

const int N=1e3+10;
using namespace std;
int n,m,H[N],L[N],ans2,ans1;
int f[N],c[N];

int main()
{
    freopen("neighbor.in","r",stdin);
    freopen("neighbor.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)scanf("%d",&H[i]);
    for(int i=1; i<=m; i++)scanf("%d",&L[i]);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            ans2+=min(H[i],L[j]);
    for(int i=1; i<=n; i++)f[H[i]]++;
    for(int i=1; i<=m; i++)c[L[i]]++;
    for(int i=0; i<=1000; i++) ans1+=max(f[i],c[i])*i;
    printf("%d %d
",ans1,ans2);
    return 0;
}
折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
原文地址:https://www.cnblogs.com/L-Memory/p/7498235.html