0SGU 128 snake (&& ZOJ 3521) 尺取,排序二叉树,线段树 难度:2
128. Snake
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
There are N points given by their coordinates on a plane. All coordinates (xi,yi) are integers in a range from -10000 up to 10000 inclusive . It is necessary to construct a broken line satisfying the following conditions:
1. The broken line should be closed.
2. End points of each segment (verteces) of the broken line can only be the given points, and all given points should be used.
3. Each two consecutive segments of the broken line should form a corner of 90 degrees in each vertex point.
4. The sides of the broken line should be parallel to coordinate axes.
5. The broken line should have no self-crossing and self-contact.
6. The broken line should have the minimal length.
You have to either find the length L of the constructed broken line, or determine that it is impossible to construct such a broken line.
Input
First line contains the number N (4 <= N <= 10000) - amount of points. Each of the following N lines contains coordinates of points separated by space xi and yi (1 <= i <= N). Points are given in random order.
Output
First line should contain the length of the broken line L or 0 if there is no solution.
Sample Input
Sample Output
4
0 0
0 3
3 3
3 0
Sample Output
12
看了题解,发现这个不自交是每个点只有两条边的意思,所以必然从左下角出发只有一个解,注意到这一点之后胡乱搞搞就过了,,,,
大概就是,首先确定整个图是由平行于x,y轴线段组成的,每个点的度都是2的图
然后,对每个x段,在起点取y值,在终点去掉y值,对应在线段树上就是起点时+1,终点时-1,x段互相之间必然不相交
所以统计是否相交只需要看y段和x段是否交,对所有的y段看是否有(y1,y2)的开区间内的点y0已经存在线段树上了(也就是有一条高度为y1<y0<y2的线段,这个时候线段还在树上所以x1<=x
<=x2)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lx (x<<1)
#define rx ((x<<1)|1)
#define MID ((l+r)>>1)
const int maxn=10001;
int n;
int dat[maxn<<4];
struct pnt{
int x,y,ind;
}p[maxn];
int e[maxn][3],len[maxn];
bool vis[maxn*2];
void dfs(int s){
vis[s]=true;
for(int i=0;i<2;i++){
int to=e[s][i];
if(!vis[to])dfs(to);
}
}
bool cmpx(pnt p1,pnt p2){
if(p1.x!=p2.x)return p1.x<p2.x;
return p1.y<p2.y;
}
bool cmpy(pnt p1,pnt p2){
if(p1.y!=p2.y)return p1.y<p2.y;
return p1.x<p2.x;
}
void update(int pos,int del ,int l,int r,int x){
if(l==r){dat[x]+=del;return ;}
if(pos<=MID)update(pos,del,l,MID,lx);
else update(pos,del,MID+1,r,rx);
dat[x]=dat[lx]+dat[rx];
}
int query(int L,int R,int l,int r,int x){
if(L<=l&&r<=R)return dat[x];
int ans=0;
if(L<=MID)ans+=query(L,R,l,MID,lx);
if(MID<R)ans+=query(L,R,MID+1,r,rx);
return ans;
}
void addedge(int f,int t){
if(len[f]<3)e[f][len[f]++]=t;
if(len[t]<3)e[t][len[t]++]=f;
}
int main(){
scanf("%d",&n);
int maxy=0;
for(int i=0;i<n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
p[i].x+=maxn;
p[i].y+=maxn;
maxy=max(maxy,p[i].y);
}
sort(p,p+n,cmpx);
for(int i=0;i<n;i++){
p[i].ind=i;
}
int ans=0;
sort(p,p+n,cmpy);
for(int i=1;i<n;i+=2){
if(p[i].y==p[i-1].y){addedge(p[i-1].ind,p[i].ind);ans+=p[i].x-p[i-1].x;}
}
sort(p,p+n,cmpx);
for(int i=1;i<n;i+=2){
if(p[i].x==p[i-1].x){addedge(p[i-1].ind,p[i].ind);ans+=p[i].y-p[i-1].y;}
}
for(int i=0;i<n;i++){
if(len[i]!=2){puts("0");return 0;}
}
dfs(0);
for(int i=0;i<n;i++){
if(!vis[i]){puts("0");return 0;}
}
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++){
int x1=p[i].x,x2=p[e[i][0]].x;
int y1=p[i].y,y2=p[e[i][1]].y;
if(vis[i])update(y1,-1,1,maxy,1);
int k1=y2>2?query(1,y2-1,1,maxy,1):0;//因为是重叠着做的而不是分开来更新所有x再检验的,也就是说这个x对应的y需要被取下但是还没取,所以通过事件顺序没法规范发生,需要注意去掉端点问题
int k2= query(1,y1,1,maxy,1);
if(y2-y1>1 && (k1-k2)>0){puts("0");return 0;}
if(!vis[i])update(y1,1,1,maxy,1);
vis[i] = !vis[i];
vis[e[i][0]] = !vis[e[i][0]];
}
printf("%d\n",ans);
return 0;
}
0SGU 128 snake (&& ZOJ 3521) 尺取,排序二叉树,线段树 难度:2的更多相关文章
- 【BZOJ4552】排序(线段树,二分答案)
[BZOJ4552]排序(线段树,二分答案) 题面 BZOJ 题解 好神的题啊 直接排序我们做不到 怎么维护? 考虑一下,如果我们随便假设一个答案 怎么检验它是否成立? 把这个数设成\(1\),其他的 ...
- 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)
2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...
- ZOJ 3521 Fairy Wars oj错误题目,计算几何,尺取法,排序二叉树,并查集 难度:2
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3521 ATTENTION:如果用long long 减小误差,这道题只能用 ...
- ZOJ 1610 Count the Colors (线段树区间更新)
题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...
- ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)
ZOJ 3597 题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你 ...
- ZOJ 1859 Matrix Searching(二维线段树)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859 Matrix Searching Time Limit: 10 Seco ...
- zoj 1610 Count the Colors(线段树延迟更新)
所谓的懒操作模板题. 学好acm,英语很重要.做题的时候看不明白题目的意思,我还拉着队友一块儿帮忙分析题意.最后确定了是线段树延迟更新果题.我就欣欣然上手敲了出来. 然后是漫长的段错误.... 第一次 ...
- [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树
Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...
- bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
随机推荐
- STM32唯一的ID
请看如下程序: /*------------------------------------------------------------------------------------------ ...
- noip2007部分题
1.统计数字 题目描述 Description 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*109).已知不相同的数不超过10000 个,现在需要统计这些自然数各自出现 ...
- map按value值查找——find_if的使用(转载)
转载:http://www.cnblogs.com/xufeiyang/archive/2012/05/09/2491871.html CValueFind #ifndef _CVALUEFIND_H ...
- 分页器的js实现代码 bootstrap Paginator.js
参考: http://www.jb51.net/article/76093.htm 如前所述, 不要什么都想到 jquery的 脚本js, 应该首先推荐的是 css 和 元素本身的事件 函数 如: o ...
- 李白打酒|2014年蓝桥杯B组题解析第三题-fishers
李白打酒 话说大诗人李白,一生好饮.幸好他从不开车. 一天,他提着酒壶,从家里出来,酒壶中有酒2斗.他边走边唱: 无事街上走,提壶去打酒. 逢店加一倍,遇花喝一斗. 这一路上,他一共遇到店5次,遇到花 ...
- Winform中使用折叠窗口
使用此处的控件 http://www.codeproject.com/Articles/18401/XPanderControls 注意事项 使用之前需要先添加winform自带的toolStripC ...
- 第四章 消息摘要算法--SHA
注意:本节内容主要参考自<Java加密与解密的艺术(第2版)>第6章“验证数据完整性--消息摘要算法” 4.1.SHA 原理:消息摘要长度(可以定量为加密后的字符串的长度)越长,安全性越高 ...
- C#下载歌词文件
前段时间写了一篇c#解析Lrc歌词文件,对lrc文件进行解析,支持多个时间段合并.本文借下载歌词文件来探讨一下同步和异步方法. Lrc文件在网络上随处可见,我们可以通过一些方法获取,最简单的就是别人的 ...
- 【Coursera】SecondWeek(1)
全球互联网的始祖 APRANET APRANET 是 DARPA(美国国防部高级研究计划局) 开发的世界上第一个运营PacketSwitching(分包交换)的网络. 鉴于二战后世界格局两极化的历史背 ...
- [异常记录-12]Web Deploy部署:未能连接到远程计算机,请确保在远程计算机上安装了 Web Deploy 并启动了所需的进程("Web Management Service")
Web Deploy 安装 请参考:图文详解远程部署ASP.NET MVC 5项目 如此安装后还不行, 可以在卸载后重新安装 Web Deploy 时,不要选那个经典还是典型的安装选项,选自定义安装 ...