[USACO5.3]Window Area【窗体面积】

这一道题没有想象中的那么难

(1)建立窗

用一个a数组来,a[][1]表示左上角的x坐标,a[][2]表示左上角的y坐标,a[][3]和a[][4]也是一样的a[head][]表示第head层的窗户坐标,记得是层

(2)

把窗户置顶把表示最高层的head+1,然后把当前的窗户放上去,在把以前的窗户删掉

(3)把窗户置底

把表示队尾tail--,再向(2)那样就可以了

(4)求百分比

dfs搜索,我们只用搜索比自己层数高的就可以了,到顶还有面积就ans=ans+这个面积,搜索就可以这样:

听说过旋图吗,我们要找的面积为矩形

假设这个矩形为一开始为:

000000

000000

000000

000000

被覆盖以后为(覆盖的矩形用1表示):

000000

001100

001100

000000

把其他的分为四份:

2222 33

55 11 33

55 11 33

55 4444

向这四个方向搜索就好了

这样可以保证不重复,而且 不需要离散化

上代码:

#include<bits/stdc++.h>
using namespace std;
int a[2100][5];
int f[210];//f表示编号所在的层数 
char s[51];//输入的数组 
int head,tail,ans;
void dfs(int k,int x1,int y1,int x2,int y2)//k表示找到第k层,当前可以看到的左上角和右下角 
{
    if(x1==x2 || y1==y2) return;//如果没有面积了,就不存在了 
    if(k>head)//如果超过了头 
    {
        ans=ans+(x2-x1)*(y2-y1);return;//就记录这一个面积 
    }
    int tx1=a[k][1],ty1=a[k][2];
    int tx2=a[k][3],ty2=a[k][4];
    if(tx1>=x2 || ty1>=y2 || tx2<=x1 || ty2<=y1)//如果这层的覆盖和矩形没关系,就找下一层 
    {
        dfs(k+1,x1,y1,x2,y2);return;
    }
    if(x1>=tx1 && x2<=tx2 && y1>=ty1 && y2<=ty2) return;//如果完全覆盖了,也没有必要找下去了 
    dfs(k+1,x1,y1,max(tx1,x1),min(ty2,y2));//按照刚才说的搜索 
    dfs(k+1,x1,min(y2,ty2),min(x2,tx2),y2);
    dfs(k+1,min(x2,tx2),max(y1,ty1),x2,y2);
    dfs(k+1,max(tx1,x1),y1,x2,max(y1,ty1));
}
int main()
{
    int i,x1,y1,x2,y2,k;
    head=200;tail=201;
    while(scanf("%s",s)!=EOF)//建议大家以字符串输入,不然会很麻烦 
    {
        if(s[0]=='w')//建立一个窗 
        {
            head++;f[s[2]]=head;
            k=4;
            for(i=1;i<=4;i++)//四个坐标 
            {
                while(isdigit(s[k])==true)//如果是数组的话 if(s[k]>='0' && s[k]<='9')  
                {
                    a[head][i]=a[head][i]*10+s[k]-'0';k++;
                }
                k++;//跳过“,” 
            }
            x1=a[head][1];y1=a[head][2];//改为左上角和右下角的坐标 
            x2=a[head][3];y2=a[head][4];
            a[head][1]=min(x1,x2);a[head][2]=min(y1,y2);
            a[head][3]=max(x1,x2);a[head][4]=max(y1,y2);
        }
        else if(s[0]=='t')//置顶 
        {
            k=f[s[2]];
            head++;f[s[2]]=head;
            for(i=1;i<=4;i++) a[head][i]=a[k][i],a[k][i]=INT_MAX;//变为无限大 
        }
        else if(s[0]=='b')//置底 
        {
            k=f[s[2]];
            tail--;f[s[2]]=tail;
            for(i=1;i<=4;i++) a[tail][i]=a[k][i],a[k][i]=INT_MAX;
        }
        else if(s[0]=='d')//删除 
        {
            k=f[s[2]];f[s[2]]=0;
            for(i=1;i<=4;i++) a[k][i]=INT_MAX;
        }
        else//求可以看到的面积 
        {
            k=f[s[2]];ans=0;
            dfs(k+1,a[k][1],a[k][2],a[k][3],a[k][4]);//深搜 
            k=(a[k][3]-a[k][1])*(a[k][4]-a[k][2]);
            printf("%.3lf\n",double(ans)/double(k)*double(100));//输出 
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zsyzclb/article/details/80580309
今日推荐