hud 2013腾讯编程马拉松 威威猫系列故事——晒被子
来源:互联网 发布:json封装 编辑:程序博客网 时间:2024/05/17 08:47
生活还要继续,太阳也照常升起,今天,威威猫在第一象限晒了N条矩形的被子,被子的每条边都和坐标轴平行,不同被子的某些部分可能会叠在一起。这时候,在原点处突然发了场洪水,时间t的时候,洪水会蔓延到( t, t ),即左下角为( 0, 0 ) ,右上角为( t, t )的矩形内都有水。
悲剧的威威猫想知道,在时间t1, t2, t3 ... tx 的时候,他有多少面积的被子是湿的?
每组数据的第一行首先是一个整数N,表示有N条被子;
接下来N行,每行包含四个整数x1, y1, x2, y2,代表一条被子的左下角和右上角的坐标;
然后接下来一行输入一个整数x,表示有x次询问;
再接下来x行,输入x个严格单调递增的整数,每行一个,表示威威猫想知道的时间ti。
[Technical Specification]
T <= 5
0 < N <= 20000
1 <= x1 < x2 <= 200000
1 <= y1 < y2 <= 200000
1 <= x <= 20000
1 <= ti <= 200000 (1 <= i <= x )
121 1 3 3 2 2 4 4512345
01588
解题思路:
如图所示
如上:
当矩形在对角线的某一侧时,是最简单的。假设是对角线下方。。只要让result[x1] ----- result[x2+1] 之间的值加上y2 - y1 就行了
实现是这样的“ 让matrix[x1+1] = y2 - y1; matrix[x2+1] = y1 - y2; (加一是因为面积在当前点才开始生效)
(for i = x1 ---> x2) gg += matrix[i]; result[i] = result[i-1]+ gg;
明显在i== x1+1 的时候 gg = y2 - y1 ,以后再x1 到 x2 之间的result都会加 y2 - y2 在x2 + 1处加上 y1 - y 2 ,gg == 0了
当是正方形的时候,假设只有一个正方形,在x1 处 vx = 1;以后每个在 x1 到x2之间的result += 1(vx)
当是明显正方形每扩大一个就要增加两个单位面积 于是 设 fx += vx 这样以后每步都可以把两边多出的面积加起来了。
让result += fx * 2 + fv 但是当正方形消失了怎么办呢? 那么再建立一个数组 flag[] 在正方形消失的位置修改fv ,这个位置fv = fv - 正方形当前的高度,
那么之后这个正方形就不影响了 因为 fx,vx == 0了
假设是其他情况发生,那么他们都可以被分解成上面说的矩形和正方形, 于是算法得出了。
复杂度是 200000的 ,优化的效果不明显 就假设是o(N)的吧
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
__int64 matrix[200009];//记录普通矩形影响
__int64 result[200009];//结果
__int64 flag [200009];//消除已经消失的正方形影响
__int64 square[200009];//记录正方形开始点
int query[20009];//查询
void haha(int low, int high)//处理正方形情况
{
if(low >= high) return ;
square[low+1] += 1;
square[high+1] -= 1;
flag[high+1] -= (high - low);
}
void make(int low,int high, int width)//处理普通矩形
{
if(width <= 0) return;
matrix[low+1] += width;
matrix[high+1] -= width;
}
int main()
{
int t;
scanf("%d",&t);
__int64 gg = 0;
__int64 fx = 0;
__int64 vx = 0;
int x1,x2,y1,y2, N;
__int64 lager;
while(t--)
{
memset(matrix, 0, sizeof(matrix));
memset(flag, 0, sizeof(flag));
memset(square, 0, sizeof(square));
scanf("%d",&N);
int maxM = 0;
lager = 0;
for(int i = 0;i < N; i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
maxM = max(maxM,x2);//用于优化的,其实可以不用
maxM = max(maxM,y2);
if(x1 > y1)//右下角
{
make(x1,x2,min(x1,y2)-y1);
}
if(x2 > y2)//右上角
{
make(y2,x2,y2-max(x1,y1));
}
if(y1 > x1)//左下角
{
make(y1,y2,min(x2,y1)-x1);
}
if(x2 < y2)//左上角
{
make(x2,y2,x2-max(x1,y1));
}
haha(max(x1,y1),min(x2,y2));//正方形
}
int q ,maxn1 = 0;
scanf("%d",&q);
int f = 0;
for(int i = 0;i < q; i++)
{
scanf("%d",&query[i]);
maxn1 = max(maxn1,query[i]);//用于优化的,
}
for(int i = 0;i < maxn1+10 ;i++)//枚举每个时间t下被影响的面积
{
if(maxM + 3 < i) break;
gg += matrix[i];
vx += square[i];
fx += flag[i];
result[i] = result[i-1]+ gg + vx + fx*2;
lager = max(lager,result[i]);
fx += vx;
}
for(int i = 0;i < q; i++)
{
if(query[i] > maxM + 3) printf("%I64d\n",lager);
else printf("%I64d\n",result[query[i]]);
}
}
return 0;
}
- hud 2013腾讯编程马拉松 威威猫系列故事——晒被子
- 威威猫系列故事——晒被子
- 腾讯马拉松编程大赛威威猫系列故事——吃鸡腿 java编程解法
- 腾讯编程马拉松初赛第五场 - 第一题(威威猫系列故事——吃鸡腿)
- 威威猫系列故事——吃鸡腿(3月25号腾讯编程马拉松大赛 )
- 【腾讯第二届校园编程马拉松】HDU-4525,威威猫系列故事——吃鸡腿
- 腾讯马拉松 威威猫系列故事——拼车记
- HDOJ 4509 湫湫系列故事——减肥记II(2013腾讯编程马拉松)
- 湫湫系列故事——植树节(2013腾讯编程马拉松初赛)
- HDU 4525 威威猫系列故事——吃鸡腿 2013腾讯编程马拉松初赛第五场第一题
- HDOJ4525 威威猫系列故事——吃鸡腿 (数论) && 腾讯2013编程马拉松第5场第一题
- 2013腾讯编程马拉松初赛第〇场(HDU 4504)威威猫系列故事——篮球梦
- hdu4533-威威猫系列故事——晒被子
- HDU 4533 威威猫系列故事——晒被子
- Hdu 4533 威威猫系列故事——晒被子
- hdu 4533 威威猫系列故事——晒被子
- hdu 4533 威威猫系列故事——晒被子
- HDOJ 4533 威威猫系列故事——晒被子
- 地址/地名翻译常识
- JAVA编码规范
- HDU 4508 湫湫系列故事——减肥记I
- HDU 2084 树塔
- Typedef 的应用小结
- hud 2013腾讯编程马拉松 威威猫系列故事——晒被子
- mips 平台linux系统软浮点
- HDU 4509 湫湫系列故事——减肥记II
- The DefaultButton of must be the ID of a control of type IButtonControl
- 新发布被百度收录的文章权重很高的原因
- linux C高手成长过程---书籍推荐
- 多线程与异步的区别
- android中查找某个Activity中的view
- Hibernate缓存机制