USACO Section 5.3 Window Area

28 篇文章 0 订阅

题意:

对于Windows窗体有5种操作  放在最顶、放在最低、添加窗体、删除窗体、询问窗体有百分之几是可见的(没被挡住)


思路:

放在最顶和最低的操作就是变换一下顺序  我用一个数组存的窗体顺序

添加窗体就是在顶部加个窗体  删除窗体我是先把要删除的移到最顶  然后顺序数组减一

询问是考点  不过做过了矩形分割那个题思路很快就有了  除了我感觉代码写着有点麻烦没什么难度  就是递归的分割可见部分  最后求面积就好了

WA了一次  注意题意说的创建窗口时给出的是对角坐标  (不一定是左上角右下角、可能是左下角右上角 - -b)


代码:

/*
ID: housera1
PROG: window
LANG: C++
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define N 70
#define M 500

int tot=-1,ans;
char order[N];
struct win
{
    int up,dn,lf,rt;
}f[M];

void dfs(int up,int lf,int dn,int rt,int floor)
{
    //printf("%d (%d,%d) (%d,%d)\n ",floor,up,lf,dn,rt);
    if(floor>tot)
    {
        ans+=(up-dn)*(rt-lf);
        return ;
    }
    int i=order[floor];
    if( up<=f[i].dn || dn>=f[i].up || lf>=f[i].rt || rt<=f[i].lf ) dfs(up,lf,dn,rt,floor+1);
    else if( up<=f[i].up && dn>=f[i].dn && lf>=f[i].lf && rt<=f[i].rt ) return ;
    else
    {
        if(f[i].up>dn&&f[i].up<up) dfs(up,lf,f[i].up,rt,floor+1);
        if(f[i].dn>dn&&f[i].dn<up) dfs(f[i].dn,lf,dn,rt,floor+1);
        up=min(up,f[i].up); dn=max(dn,f[i].dn);
        if(f[i].lf>lf&&f[i].lf<rt) dfs(up,lf,dn,f[i].lf,floor+1);
        if(f[i].rt>lf&&f[i].rt<rt) dfs(up,f[i].rt,dn,rt,floor+1);
    }
}

int main()
{
    int Debug=0;
    if(!Debug)
    {
        freopen("window.in","r",stdin);
        freopen("window.out","w",stdout);
    }
    char op,id;
    int i,up,dn,lf,rt;
    while(~scanf("%c",&op))
    {
        if(op=='w')
        {
            scanf("(%c,%d,%d,%d,%d)",&id,&lf,&up,&rt,&dn);
            if(dn>up) swap(dn,up);
            if(lf>rt) swap(lf,rt);
            f[id].up=up; f[id].dn=dn; f[id].lf=lf; f[id].rt=rt;
            tot++;
            order[tot]=id;
        }
        else if(op=='t'||op=='d')
        {
            scanf("(%c)",&id);
            for(i=0;i<tot;i++)
            {
                if(order[i]==id) swap(order[i],order[i+1]);
            }
            if(op=='d') tot--;
        }
        else if(op=='b')
        {
            scanf("(%c)",&id);
            for(i=tot;i>0;i--)
            {
                if(order[i]==id) swap(order[i],order[i-1]);
            }
        }
        else
        {
            scanf("(%c)",&id);
            for(i=0;i<=tot;i++)
            {
                if(order[i]==id)
                {
                    ans=0;
                    up=(f[id].up-f[id].dn)*(f[id].rt-f[id].lf);
                    dfs(f[id].up,f[id].lf,f[id].dn,f[id].rt,i+1);
                    printf("%.3f\n",100.0*ans/up);
                    break;
                }
            }
        }
        getchar();
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值