1 条题解

  • 0
    @ 2025-8-24 21:41:06

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 「QQ红包」
    **

    搬运于2025-08-24 21:41:06,当前版本为作者最后更新于2017-07-08 23:48:48,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题解by:redbag

    大概思路同楼下

    先离散,然后再根据顺序把该减的减掉,该标记的标记,具体见代码

    
    /*
    ID: ylx14271
    PROG: window
    LANG: C++
    */
    #include<set>
    #include<map>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath> 
    #include<iostream>
    #include<algorithm>
    using namespace std;
    char ch;
    int x,y,x1,y12;
    int n;//存窗户的个数/标号
    struct node
    {
        int x1,x2,y11,y2;
        int id,deep,flag;
    } a[2500];//存每个窗户的四个边界(x1:左,x2:右,y1:下,y2:上 
    map<char,int> a1;
    int max1,min1;
    int zx[2500],lx,ux[45000];
    int zy[2500],ly,uy[45000];
    int f[250][250];
    void sum(int x)
    {
        memset(f,0,sizeof(f));
        lx=0;ly=0;
        for (int i=1;i<=n;i++)
        {
            if (a[i].flag==0||a[i].deep<a[x].deep) continue;//压在下面的或者不存在的不要处理 
            zx[++lx]=a[i].x1;zx[++lx]=a[i].x2; 
            zy[++ly]=a[i].y11;zy[++ly]=a[i].y2;//存坐标 
        }
        sort(zx+1,zx+lx+1);//排序 
        sort(zy+1,zy+ly+1); 
        
        int t=0;
        for (int i=1;i<=lx;i++)
        {
            //cout<<zx[i]<<" ";
            if (zx[i]!=zx[i-1])
            {
                t++;
                zx[t]=zx[i];
                ux[zx[i]]=t;
            }
        } 
        lx=t;
        //离散 
        t=0;
        for (int i=1;i<=ly;i++)
        {
            //cout<<zy[i]<<" ";
            if (zy[i]!=zy[i-1])
            {
                t++;
                zy[t]=zy[i];
                uy[zy[i]]=t; 
            }
        } 
        ly=t;
        //离散 
    
        for (int i=ux[a[x].x1];i<=ux[a[x].x2]-1;i++)
            for (int j=uy[a[x].y11];j<=uy[a[x].y2]-1;j++)
            f[i][j]=1;//窗户部分标记 
        for (int i=1;i<=n;i++)
            if (a[i].deep>a[x].deep&&a[i].flag==1)
            {
                for (int j=ux[a[i].x1];j<=ux[a[i].x2]-1;j++)
                    for (int k=uy[a[i].y11];k<=uy[a[i].y2]-1;k++)
                    f[j][k]=0;
            }//有其他窗户覆盖在上面的也标记 
        double sum1=0.0;
        for (int i=1;i<lx;i++)
            for (int j=1;j<ly;j++)
            {
                sum1+=f[i][j]*(zx[i+1]-zx[i])*(zy[j+1]-zy[j]);
            }//算面积 
        double x1=100*(double)(sum1)/(double)((a[x].x2-a[x].x1)*(a[x].y2-a[x].y11));
        printf("%.3lf\n",x1);//输出 
        return;
    }
    int main()
    {
        freopen("window.in","r",stdin);
        freopen("window.out","w",stdout);
        while (scanf("%c",&ch)!=EOF)
        {
            if (ch=='w')
            {
                scanf("(%c,%d,%d,%d,%d)",&ch,&x,&y,&x1,&y12);
                n++;//存有多少个 
                a1[ch]=n;//ch的编号存起来 
                a[n].x1=min(x,x1);a[n].x2=max(x,x1);
                a[n].y11=min(y,y12);a[n].y2=max(y,y12);
                a[n].id=ch;a[n].flag=1;
                max1++;//全部存起来 
                a[n].deep=max1;//存深度 
            } else
            if (ch=='t')//置顶 
            {
                scanf("(%c)",&ch);
                a[a1[ch]].deep=++max1;
            } else
            if (ch=='b')//置底 
            {
                scanf("(%c)",&ch);
                a[a1[ch]].deep=--min1;
            } else
            if (ch=='d')//删除 
            {
                scanf("(%c)",&ch);
                a[a1[ch]].flag=0;
            } else
            if (ch=='s')//统计 
            {
                scanf("(%c)",&ch);
                sum(a1[ch]); 
            } 
            getchar();getchar();//洛谷有行末空格 
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1775
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者