luogu【P2745】[USACO5.3]窗体面积Window Area
这个题 就是个工程题 (然而一开始我并不知道怎么做。。还是看nocow的。。qwq)(原题入口)
算法为 离散化 + 扫描线 将大坐标变小 并且 用横纵坐标进行扫描 来计算面积
一开始 我想边添加 点的坐标 边 离散 后来发现 有点问题
因为 它离散后的坐标 并不是按顺序来排(因为后来可能还加入中间的点 就需要重新离散)
所以 我就把一开始的操作 和 坐标先存下来 进行离散 再进行操作 (QAQ 搞了好久)
后面 就是计算面积了 把一个大矩形 划分成 许多个小矩形 再进行标记 来计算面积了
代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cctype>
#include <iostream>
#include <map>
#include <vector>
#define For(i, l, r) for(int i = (l); i <= (int)(r); ++i)
#define Fordown(i, r, l) for(int i = (r); i >= (int)(l); --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define pb push_back
using namespace std; inline int read(){
int x = , fh = ; char ch;
for(; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -;
for(; isdigit(ch); ch = getchar()) x = (x<<) + (x<<) + (ch^'');
return x * fh;
} const int N = ;
map <int, int> fx, fy; //map数组 记录这个坐标是否被离散化过
int gx[<<], gy[<<]; //反向存储标号对应的坐标
int cnt_x = , cnt_y = , cnt = ; //离散化的个数
char id[N]; //记录id数组 int now_deep = *(<<), top_deep = (<<), back_deep = *(<<);
struct node {
int xl, yl, xr, yr;
int deep; //层次
bool flag; //是否被删除
};
node win[N]; //存储窗户 int idx(char ch) {
For (i, , cnt)
if (id[i] == ch) return i;
id[++cnt] = ch;
return cnt;
} //计算当前l的id bool exist[N/][N/];
double sum(int num) {
if (!win[num].flag) return 0.0000; //如果已经删除 就返回0.0 (好像并没有用)
Set(exist, false); //判断小矩形是否存在
int sum_area = ;
int now_area = ; For (i, win[num].xl, win[num].xr-)
For (j, win[num].yl, win[num].yr-)
{ exist[i][j] = true; //一开始置为真
sum_area += fabs ((gx[i+] - gx[i] ) * (gy[j+] - gy[j]) ) ; } //计算本来的总面积 For (i, , cnt)
if (win[i].flag && win[i].deep < win[num].deep) //如果在它上面 并且 未被删除
For (j, win[i].xl, win[i].xr-)
For (k, win[i].yl, win[i].yr-)
exist[j][k] = false; //小矩形置为假 For (i, win[num].xl, win[num].xr-)
For (j, win[num].yl, win[num].yr-)
if (exist[i][j]) //存在 就加上
now_area += fabs( (gx[i] - gx[i+]) * (gy[j] - gy[j+]) ); //计算面积 return ((double)now_area / (double)sum_area * 100.0000); //计算百分比
} struct oper {
char opt;
int l, xl, yl, xr, yr;
}; oper kk[N]; //存储操作
int cnt_op = ;
vector <int> tx; //存储坐标
vector <int> ty; int main(){
freopen ("window.in", "r", stdin);
freopen ("window.out", "w", stdout);
char opt;
while (scanf ("%c", &opt) != EOF) {
char l;
int xl1, yl1, xr1, yr1;
if (opt == 'w') {
scanf ("(%c,%d,%d,%d,%d)", &l, &xl1, &yl1, &xr1, &yr1);
if (xl1 > xr1) swap(xl1, xr1);
if (yl1 > yr1) swap(yl1, yr1); //左下角 和 右上角
kk[++cnt_op] = (oper) {opt, l, xl1, yl1, xr1, yr1};
tx.pb (xl1); tx.pb(xr1); ty.pb(yl1); ty.pb(yr1);
}
else {
scanf ("(%c)", &l);
kk[++cnt_op] = (oper) {opt, l, , , , };
}
} sort (tx.begin(), tx.end() );
For (i, , tx.size() - )
if (!fx[tx[i]] ) {fx[tx[i]] = ++cnt_x; gx[cnt_x] = tx[i]; }
sort (ty.begin(), ty.end() );
For (i, , ty.size() - )
if (!fy[ty[i]] ) {fy[ty[i]] = ++cnt_y; gy[cnt_y] = ty[i]; }
//运用map的离散化 可能有点慢 For (i, , cnt_op) {
//cout << "id: " << i << endl;
opt = kk[i].opt;
char l = kk[i].l; int num;
int xl1 = kk[i].xl, yl1 = kk[i].yl, xr1 = kk[i].xr, yr1 = kk[i].yr;
if (opt == 'w') {
num = idx(l);
win[num].xl = fx[xl1]; win[num].xr = fx[xr1];
win[num].yl = fy[yl1]; win[num].yr = fy[yr1];
win[num].flag = true; win[num].deep = --top_deep; //放在最上面 并将flag为真
} //创建一个新窗体(window)
else if (opt == 't') {
num = idx(l);
win[num].deep = --top_deep;
}//将窗体置顶(top)
else if (opt == 'b') {
num = idx(l);
win[num].deep = ++back_deep;
}//将窗体置底(back)
else if (opt == 'd') {
num = idx(l);
win[num].flag = false;
// cout << num << endl;
}//删除一个窗体(delete)
else if (opt == 's') {
num = idx(l);
printf ("%.3lf\n", sum(num));
}//输出窗体可见部分的百分比(sum)
}
}
luogu【P2745】[USACO5.3]窗体面积Window Area的更多相关文章
- [洛谷P2745] [USACO5.3]窗体面积Window Area
洛谷题目链接:[USACO5.3]窗体面积Window Area 题目描述 你刚刚接手一项窗体界面工程.窗体界面还算简单,而且幸运的是,你不必显示实际的窗体.有 5 种基本操作: 创建一个新窗体 将窗 ...
- 无废话ExtJs 入门教程三[窗体:Window组件]
无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...
- USACO 5.3 Window Area
Window AreaIV Balkan Olympiad You've just be assigned the project of implemented a windowing interfa ...
- [Luogu P1345] [USACO5.4]奶牛的电信Telecowmunication (最小割)
题面 传送门:https://www.luogu.org/problemnew/show/P1345 ] Solution 这道题,需要一个小技巧了解决. 我相信很多像我这样接蒟蒻,看到这道题,不禁兴 ...
- 洛谷U2641 木板面积(area)——S.B.S.
题目背景 一年一次的夏令营又要开始了,卡卡西和小伙伴们早就做好了准备,满心期 待着这趟快乐之旅.在一个阳光明媚的清晨,卡卡西在老师的带领下来到了这次 夏令营的首站——“神奇木材加工厂” . 题目描述 ...
- [Swift]LeetCode223. 矩形面积 | Rectangle Area
Find the total area covered by two rectilinear rectangles in a 2D plane. Each rectangle is defined b ...
- [Swift]LeetCode695. 岛屿的最大面积 | Max Area of Island
Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...
- LeetCode 223. 矩形面积(Rectangle Area)
223. 矩形面积 223. Rectangle Area 题目描述 在二维平面上计算出两个由直线构成的矩形重叠后形成的总面积. 每个矩形由其左下顶点和右上顶点坐标表示,如图所示. LeetCode2 ...
- 面积(area)
题目描述 编程计算由"*"号围成的下列图形的面积.面积计算方法是统计*号所围成的闭合曲线中点的数目.如图所示,在10*10的二维数组中,“*”围住了15个点,因此面积为15. 0 ...
随机推荐
- Spring基础篇——通过Java注解和XML配置装配bean
自动化装配的确有很大的便利性,但是却并不能适用在所有的应用场景,比如需要装配的组件类不是由自己的应用程序维护,而是引用了第三方的类库,这个时候自动装配便无法实现,Spring对此也提供了相应的解决方案 ...
- 'abc' 转换成[a, b, c]一道面试题的思考
最近面试遇到那样一个问题把'abc' 转换成[a, b, c],就是字符串转成数组. 看着简单,我就是说split,然后面试官问还有吗.我有思考了一下.循环用charAt()取,然后还有Array.f ...
- SpringMVC常见注解
@RequestParam( value="name", require=false ) String wrap 参数绑定:require=false 表示前端对 name 这个 ...
- Go语言极速入门手册
Github: https://github.com/coderzh/CodeTips /* gotips_test.go: Golang速学速查速用代码手册 Source: github.com/c ...
- 【NOIP2015】字串
[NOIP2015]字串 标签: DP NOIP Description 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其 ...
- win7下通过easyBCD引导安装Ubuntu16.04(并处理遇到的坑)
Ubuntu16.04作为目前最新版本的ubuntu系统,相信很多人都想在自己的电脑上安装一下,然而系统的安装方法各式各样,u盘法.grub引导法等等,这里我将介绍在win7系统下用easyBCD软件 ...
- Docker 入门之创建service(一)
在一个分布式应用中,我们把应用的不同层叫做"Services".比如,一个视频共享应用,它包含存储数据到数据库的服务,用户上载后后台进行的视频解码服务,前端服务等等. 然而,一个服 ...
- Apache服务器安装-apache已经卸载,如何删除注册在系统的服务
cmd进入windows的命令行客户端,执行:sc delete apache 注意:以管理员的身份删除,同理,此方法也可以删除其他类似的服务.例如sc delete MongoDB.
- MysqL碎片整理优化
先来说一下什么是碎片,怎么知道碎片有多大! 简单的说,删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来.于是造成了数据的存储位置不连续,以及物理存储顺序与理论 ...
- 【重磅】PRO基础版免费,是时候和ExtJS说再见了!
三石的新年礼物 9 年了,FineUI(开源版)终于迎来了她的继任者 - FineUIPro(基础版),并且完全免费! FineUIPro(基础版)作为三石奉献给社区的一个礼物,绝对让你心动: 拥 ...