[USACO5.3.2] 窗体面积 - 矩形切割
来源:互联网 发布:淘宝首页全屏怎么装修 编辑:程序博客网 时间:2024/05/21 08:37
题目描述
你刚刚接手一项窗体界面工程。窗体界面还算简单,而且幸运的是,你不必显示实际的窗体。有 5 种基本操作:
创建一个新窗体
将窗体置顶
将窗体置底
删除一个窗体
输出窗体可见部分的百分比(就是,不被其它窗体覆盖的部分)。
在输入文件中,操作以如下的格式出现。
创建一个新窗体:w(I,x,y,X,Y)
将窗体置顶: t(I)
将窗体置底: b(I)
删除一个窗体:d(I)
输出窗体可见部分的百分比:s(I)
I 是每个窗体唯一的标识符。表示符可以是 ‘a’..’z’, ‘A’..’Z’ 和 ‘0’..’9’ 中的任何一个。输入文件中没有多余的空格。
(x,y)和(X,Y)是窗体的对角。当你创建一个窗体的时候,它自动被“置顶”。你不能用已经存在的标识符来创建窗体,但是你 可以删除一个窗体后再用已删除窗体的标识符来创建窗体。坐标用正整数来表示,并且所有的窗体面积都不为 0(x <> X 且 y <> Y)。x 坐标和 y 坐标在 1 —— 32767 的范围内。
输入格式
输入文件包含给你的解释程序的一系列命令,每行一个。当输入文件结束时,停止程序。
输出格式
只对于 s() 命令进行输出。当然,输入文件可能有许多 s() 命令,所以输出文件应该是一个百分比的序列,每行一个,百分比是窗体可见部分的百分比。百分比应该四舍五入到三位小数。
样例数据
样例输入
w(a,10,132,20,12)
w(b,8,76,124,15)
s(a)
样例输出
49.167
说明
插入操作不超过150
总操作次数不超过1000
题目分析
这应该算是usaco史上最为恶心的调试题了吧(当然素数方阵更厉害)
对于每一个窗体看做一个矩形
维护一个队列
新加的窗体加入队尾
如果要置顶一个窗体,将他从队列中转到队尾
如果要置底一个窗体,将他从队列中转到队首
如果删除一个窗体,将他从队列中删除
以上操作均不用加入切割
如果查询,那么将队列中所有窗体顺序进行切割,统计面积
查询完毕后清空矩形切割中的矩形
源代码
#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>#include<map>using namespace std;inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj;}struct Square { double x1,x2,y1,y2; char uuid; Square() {} Square(double lx,double ly,double rx,double ry,char color):x1(lx),y1(ly),x2(rx),y2(ry),uuid(color) {}};struct Cut_Square { Square a[100005]; int sum; int init() { sum=0; } bool if_intersect(Square a,Square b) { if(a.x1>=b.x2||a.y1>=b.y2||a.x2<=b.x1||a.y2<=b.y1)return false; else return true; } void add(double x1,double y1,double x2,double y2,char uuid) { a[++sum]=Square(x1,y1,x2,y2,uuid); } void del(int index) { a[index]=a[sum]; sum--; } double Xway_cut(int index,double x1,double y1,double x2,double y2) { //返回交集 double k1=max(x1,a[index].x1); double k2=min(x2,a[index].x2); if(a[index].x1<k1)add(a[index].x1,a[index].y1,k1,a[index].y2,a[index].uuid); if(k2<a[index].x2)add(k2,a[index].y1,a[index].x2,a[index].y2,a[index].uuid); return Yway_cut(index,k1,y1,k2,y2); } double Yway_cut(int index,double x1,double y1,double x2,double y2) { double k1=max(y1,a[index].y1); double k2=min(y2,a[index].y2); if(a[index].y1<k1)add(x1,a[index].y1,x2,k1,a[index].uuid); if(k2<a[index].y2)add(x1,k2,x2,a[index].y2,a[index].uuid); return (x2-x1)*(k2-k1); }};struct QueNode { char uuid; int x1,y1,x2,y2; QueNode() {} QueNode(char u,int lx,int ly,int rx,int ry):uuid(u),x1(lx),y1(ly),x2(rx),y2(ry) {}} Q[500005];Cut_Square s;int Right=0;int main() { char order,uuid; while(scanf("%c",&order)!=EOF) { if(order=='w') { //加入 int x1,y1,x2,y2; scanf("(%c,%d,%d,%d,%d)",&uuid,&x1,&y1,&x2,&y2); int tx1=x1,ty1=y1,tx2=x2,ty2=y2; x1=min(tx1,tx2); y1=min(ty1,ty2); x2=max(tx1,tx2); y2=max(ty1,ty2); Q[++Right]=QueNode(uuid,x1,y1,x2,y2); //窗体入队 } else if(order=='t') { //置顶 int pos; scanf("(%c)",&uuid); for(int i=1; i<=Right; i++) //移动队列,将指定窗口放到队尾 if(Q[i].uuid==uuid) { pos=i; break; } QueNode Now=Q[pos]; for(int i=pos; i<Right; i++)Q[i]=Q[i+1]; Q[Right]=Now; } else if(order=='b') { //置底 int pos; scanf("(%c)",&uuid); for(int i=1; i<=Right; i++) //移动队列,将指定窗口放到队首 if(Q[i].uuid==uuid) { pos=i; break; } QueNode Now=Q[pos]; for(int i=pos-1; i>=1; i--)Q[i+1]=Q[i]; Q[1]=Now; } else if(order=='d') { //删除 int pos; scanf("(%c)",&uuid); for(int i=1; i<=Right; i++) if(Q[i].uuid==uuid) { pos=i; break; } for(int i=pos; i<Right; i++)Q[i]=Q[i+1]; Right--; } else if(order=='s') { //询问 int pos; double sum=0; scanf("(%c)",&uuid); for(int i=1; i<=Right; i++) if(Q[i].uuid==uuid) { pos=i; break; } for(int i=1; i<=Right; i++) { //依次添加窗体 Square b=Square(Q[i].x1,Q[i].y1,Q[i].x2,Q[i].y2,Q[i].uuid); for(int j=1; j<=s.sum; j++) { if(!s.if_intersect(s.a[j],b))continue; //不相交 s.Xway_cut(j,b.x1,b.y1,b.x2,b.y2); s.del(j); j--; //删除完矩形移动了最后一个矩形,若j不-1可能导致原矩形未切割 } s.add(b.x1,b.y1,b.x2,b.y2,b.uuid); } for(int i=1; i<=s.sum; i++) if(s.a[i].uuid==uuid)sum+=(s.a[i].x2-s.a[i].x1)*(s.a[i].y2-s.a[i].y1); printf("%0.3lf\n",sum*100/((Q[pos].x2-Q[pos].x1)*(Q[pos].y2-Q[pos].y1))); s.init(); //清空矩阵切割数组 } } return 0;}
- [USACO5.3.2] 窗体面积 - 矩形切割
- 矩形切割-面积求并
- 拆分-洛谷P2745 [USACO5.3]窗体面积Window Area
- POJ1177矩形面积并(矩形切割+括号匹配)
- USACO5.3 IDDFS_强连通_二维树状数组_斐蜀定理_矩形切割
- 矩形切割
- 矩形切割
- 线段切割&&矩形切割
- 矩形面积
- Poj1151/HDU1542(求并矩形覆盖的面积)分别用离散化处理,矩形切割,线段树三种方法实现.
- 洛谷 P1856 [USACO5.5]矩形周长Picture
- 【矩形切割】卫星覆盖
- 【矩形切割】Atlantis
- POJ3277(矩形切割)
- HDU3634(矩形切割)
- POJ 1151 矩形切割
- [POJ1151] Atlantis - 矩形切割
- [codevs3235] 战争 - 矩形切割
- HDU 2045 不容易系列之(3)—— LELE的RPG难题 【递推】
- 早该开始了,现在正好,与bug斗,与坑斗,其乐无穷!
- 1008: FBI树
- Const Buffer,Texture Buffer
- Effective Java读书笔记七:泛型(部分章节需要重读)
- [USACO5.3.2] 窗体面积 - 矩形切割
- PHP设计模式——概述
- CodeReview工具:UpSource+SVN+Idea搭建与使用
- hihocoder #1369 : 网络流一·Ford-Fulkerson算法
- java 直接返回Date类型数据给前端,前端的处理方法
- 威佐夫博弈
- CODE[vs] 天梯 1501 二叉树最大宽度和高度
- 前端PS基础
- 1016: 守望者的逃离