题意:
对于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;
}