Window Area
IV Balkan Olympiad

You've just be assigned the project of implemented a windowing interface. This windowing interface is fairly simple, and fortunately, you don't have to display the actual windows. There are 5 basic operations:

  1. Create a window
  2. Bring a window to the top
  3. Put a window to the bottom
  4. Destroy a window
  5. Output what percentage of a window is visible (i.e., isn't covered by windows above it).

In the input, the operations appear in the following format:

  • Create window: w(I,x,y,X,Y)
  • Bring window to top: t(I)
  • Put window on bottom: b(I)
  • Destroy window: d(I)
  • Output percentage visible: s(I)

The I is a unique identifier for each window, which is one character. The character can be any of 'a'..'z', 'A'..'Z', and '0'..'9'. No extra spaces will appear in the input.

(x,y) and (X,Y) are opposite corners of the window. When a window is created, it is put `on top'. You can't create a window with an identifier that is already in use, but you can destroy a window and then create a new one with the identifier of the destroyed window. Coordinates will be positive integers, and all windows will be of non-zero area (x != X and y != Y). The x and y coordinates are between 1 and 32767 inclusive.

PROGRAM NAME: window

INPUT FORMAT

The input file consists of a sequence of commands to your interpreter. They will be listed one per line. Terminate the program when no more input is available

SAMPLE INPUT (file window.in)

w(a,10,132,20,12)
w(b,8,76,124,15)
s(a)

OUTPUT FORMAT

Output lines only for the s() commands. Of course, there might be several s() commands (but no more than 500) so the output should be a sequence of percentages, one per line, stating the percentage of the windows that are visible. The percentages should be rounded to 3 decimal places.

SAMPLE OUTPUT (file window.out)

49.167

——————————————————————————————题解

借用USACO的字符画一下

*----------------*
| |
| |
| |
| *----* |
| | | |
| | | |
| | | |
| *----* |
| |
| |
*----------------*
||
\/
*-----*----*-----*
| | | |
| | 2 | |
| | | |
| *----* |
| | | |
| 1 | | 3 |
| | | |
| *----* |
| | 4 | |
| | | |
*-----*----*-----* *-----*
| 2 |
| |
*------------------*
| |
| |
*------------------*
| 4 |
| |
*-----* *------------*
| |
*-------| |
| | |
| | |
| 1 *------------*
| | 4 |
*-------*---* 这样上下左右的切割,递归处理
前四个操作只要记录一下高度值,修改高度就可以了
 /*
ID: ivorysi
LANG: C++
PROG: window
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <string.h>
#include <cmath>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define sigongzi(j,x,y) for(int j=(x);j>(y);--j)
#define inf 0x3f3f3f3f
#define ivorysi
#define mo 97797977
#define hash 974711
#define base 47
#define pss pair<string,string>
#define MAXN 5000
#define fi first
#define se second
#define pii pair<int,int>
#define esp 1e-8
typedef long long ll;
using namespace std;
char a[];
int f,cut[];
int cnt;
struct data{
int lx,ly,rx,ry;
int h;
}window[];
int calc(char c) {
if(c>='a' && c<='z') return c-'a'+;
else if (c>='A' && c<='Z') return c-'A'+;
else if(c>='' && c<='') return c-''+;
}
void ins(int x,int y,int X,int Y,char c) {
int t=calc(c);
++cnt;
window[t].lx=min(x,X);
window[t].ly=min(y,Y);
window[t].rx=max(x,X);
window[t].ry=max(y,Y);
window[t].h=;
siji(i,,) {//这里原来打成xiaosiji忘改了
if(window[i].h!= && i!=t) ++window[i].h;
}
}
void top(char c) {
int t=calc(c);
int he=window[t].h;
window[t].h=;
siji(i,,) {
if(window[i].h!= && window[i].h<he && i!=t) ++window[i].h;
}
}
void del(char c) {
int t=calc(c);
int he=window[t].h;
window[t].h=;
siji(i,,) {
if(window[i].h!= && window[i].h>he) --window[i].h;
}
}
void bottom(char c) {
int t=calc(c);
int he=window[t].h;
window[t].h=cnt;
siji(i,,) {
if(window[i].h!= && window[i].h>he && i!=t) --window[i].h;
}
}
int solute(int k,int x1,int y1,int x2,int y2) {
if(x2<=x1 || y2<=y1) return ;
int t=k;
while(t>&&(window[cut[t]].rx <=x1 || window[cut[t]].ry<=y1
|| window[cut[t]].lx>=x2 || window[cut[t]].ly>=y2)) --t;
if(t<=) return (x2-x1)*(y2-y1); int res=;
if(window[cut[t]].lx>x1) {
res+=solute(t-,x1,y1,window[cut[t]].lx,y2);
}
if(window[cut[t]].ly>y1) {
res+=solute(t-,max(x1,window[cut[t]].lx),y1,min(x2,window[cut[t]].rx),window[cut[t]].ly);
}
if(window[cut[t]].rx<x2) {
res+=solute(t-,window[cut[t]].rx,y1,x2,y2);
}
if(window[cut[t]].ry<y2) {
res+=solute(t-,max(x1,window[cut[t]].lx),window[cut[t]].ry,min(x2,window[cut[t]].rx),y2);
}
return res;
}
void solve() {
int x1,y1,x2,y2;
while(scanf("%s",a+)!=EOF) {
if(a[]=='w') {
siji(i,,strlen(a+)) {
if(a[i]<'' || a[i] > '') a[i]=' ';
}
sscanf(a+,"%d%d%d%d",&x1,&y1,&x2,&y2);
ins(x1,y1,x2,y2,a[]);
}
else if(a[]=='t') {
top(a[]);
}
else if(a[]=='b') {
bottom(a[]);
}
else if(a[]=='d') {
del(a[]);
}
else {
f=;
int t=calc(a[]);
if(window[t].h==) {puts("0.000");continue;} siji(i,,) {
if(window[t].h>window[i].h && window[i].h!=) cut[++f]=i;
}
int sa=solute(f,window[t].lx,window[t].ly,window[t].rx,window[t].ry);
int sb=(window[t].ry-window[t].ly)*(window[t].rx-window[t].lx);
printf("%.3lf\n",(double)sa/sb*);
}
}
}
int main(int argc, char const *argv[])
{
#ifdef ivorysi
freopen("window.in","r",stdin);
freopen("window.out","w",stdout);
#else
freopen("f1.in","r",stdin);
#endif
solve();
return ;
}
 

USACO 5.3 Window Area的更多相关文章

  1. [洛谷P2745] [USACO5.3]窗体面积Window Area

    洛谷题目链接:[USACO5.3]窗体面积Window Area 题目描述 你刚刚接手一项窗体界面工程.窗体界面还算简单,而且幸运的是,你不必显示实际的窗体.有 5 种基本操作: 创建一个新窗体 将窗 ...

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

    这个题 就是个工程题 (然而一开始我并不知道怎么做..还是看nocow的..qwq)(原题入口) 算法为 离散化 + 扫描线  将大坐标变小  并且 用横纵坐标进行扫描 来计算面积 一开始 我想边添加 ...

  3. USACO 5.3 章节

    相关讲解可在USACO上看原文,也可以搜索nocow找到翻译的! (nocow上有些微翻译是有问题的,如果想看nocow翻译的建议也对着英文看) 以下记录以下 自己之前未掌握的一些要点,以及按自己的括 ...

  4. USACO 完结的一些感想

    其实日期没有那么近啦……只是我偶尔还点进去造成的,导致我没有每一章刷完的纪念日了 但是全刷完是今天啦 讲真,题很锻炼思维能力,USACO保持着一贯猎奇的题目描述,以及尽量不用高级算法就完成的题解……例 ...

  5. 转:SDL2源代码分析

    1:初始化(SDL_Init()) SDL简介 有关SDL的简介在<最简单的视音频播放示例7:SDL2播放RGB/YUV>以及<最简单的视音频播放示例9:SDL2播放PCM>中 ...

  6. Using SetWindowRgn

    Using SetWindowRgn Home Back To Tips Page Introduction There are lots of interesting reasons for cre ...

  7. SDL2源码分析2:窗体(SDL_Window)

    ===================================================== SDL源码分析系列文章列表: SDL2源码分析1:初始化(SDL_Init()) SDL2源 ...

  8. FFmpeg源代码简单分析:libavdevice的gdigrab

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  9. SDL2源代码分析2:窗口(SDL_Window)

    ===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...

随机推荐

  1. Ubuntu 搭建svn服务器 ,以及常见错误解决方案

    一.安装命令: 1)以root身份登录.执行:sudo su -命令 2)执行安装命令:apt-get install subversion   二.创建项目目录 1)mkdir  /home/svn ...

  2. WAV MP3 Converter-强大的音频转换软件-特别版

    From:http://www.cnblogs.com/killerlegend/p/3873909.html Author:KillerLegend Date:2014.7.28 WAV MP3 C ...

  3. HDU 2841 容斥 或 反演

    $n,m <= 1e5$ ,$i<=n$,$j<=m$,求$(i⊥j)$对数 /** @Date : 2017-09-26 23:01:05 * @FileName: HDU 284 ...

  4. [转载]RSA算法详解

    原文:http://www.matrix67.com/blog/archives/5100 数论,数学中的皇冠,最纯粹的数学.早在古希腊时代,人们就开始痴迷地研究数字,沉浸于这个几乎没有任何实用价值的 ...

  5. .net WebService 大数据量时性能的提高

    1.直接返回DataSet对象 [WebMethod(Description = "直接返回DataSet对象")] public DataSet GetUserListDateS ...

  6. [hadoop]mapreduce原理简述

    1.用于map的输入,先将输入数据切分成相等的分片,为每一个分片创建一个map worker,这里的切片大小不是随意订的,一般是与HDFS块大小一致,默认是64MB,一个节点上存储输入数据切片的最大s ...

  7. 【专题】平衡树(Treap,fhq-treap)

    [旋转] 平衡树中的旋转是指在不改变中序遍历的前提下改变树的形态的方式.(中序遍历=排名顺序) 右旋将当前点的左节点旋上来,左旋反之.(图侵删) void rturn(int &k){ int ...

  8. Linux查看日志三种命令

    第一种:查看实时变化的日志(比较吃内存) 最常用的: tail -f filename (默认最后10行,相当于增加参数 -n 10) Ctrl+c 是退出tail命令   其他情况: tail -n ...

  9. php empty()与isset()

    empty() : 检查一个变量是否为空. 判断一个变量是否被认为是空的.当一个变量并不存在,或者它的值等同于FALSE,那么它会被认为不存在.如果变量不存在的话,empty()并不会产生警告. em ...

  10. 移动开发关于APN的知识整理

    APN(Access Point Name),即"接入点名称",用来标识GPRS的业务种类,是通过手机上网时必须配置的一个参数,其决定了手机通过哪种接入方式来访问网络. 一.类别 ...