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的更多相关文章

  1. 【BZOJ4552】排序(线段树,二分答案)

    [BZOJ4552]排序(线段树,二分答案) 题面 BZOJ 题解 好神的题啊 直接排序我们做不到 怎么维护? 考虑一下,如果我们随便假设一个答案 怎么检验它是否成立? 把这个数设成\(1\),其他的 ...

  2. 2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串)

    2021.12.09 [HEOI2016/TJOI2016]排序(线段树+二分,把一个序列转换为01串) https://www.luogu.com.cn/problem/P2824 题意: 在 20 ...

  3. ZOJ 3521 Fairy Wars oj错误题目,计算几何,尺取法,排序二叉树,并查集 难度:2

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3521 ATTENTION:如果用long long 减小误差,这道题只能用 ...

  4. ZOJ 1610 Count the Colors (线段树区间更新)

    题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...

  5. ZOJ 3597 Hit the Target! (线段树扫描线 -- 矩形所能覆盖的最多的点数)

    ZOJ 3597 题意是说有n把枪,有m个靶子,每把枪只有一发子弹(也就是说一把枪最多只能打一个靶子), 告诉你第 i 把枪可以打到第j个靶, 现在等概率的出现一个连续的P把枪,在知道这P把枪之后,你 ...

  6. ZOJ 1859 Matrix Searching(二维线段树)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859 Matrix Searching Time Limit: 10 Seco ...

  7. zoj 1610 Count the Colors(线段树延迟更新)

    所谓的懒操作模板题. 学好acm,英语很重要.做题的时候看不明白题目的意思,我还拉着队友一块儿帮忙分析题意.最后确定了是线段树延迟更新果题.我就欣欣然上手敲了出来. 然后是漫长的段错误.... 第一次 ...

  8. [bzoj4552][Tjoi2016&Heoi2016]排序-二分+线段树

    Brief Description DZY有一个数列a[1..n],它是1∼n这n个正整数的一个排列. 现在他想支持两种操作: 0, l, r: 将a[l..r]原地升序排序. 1, l, r: 将a ...

  9. bzoj 4552: [Tjoi2016&Heoi2016]排序——二分+线段树

    Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...

随机推荐

  1. DTMF在VOIP中的解决方案

    双音多频DTMF(Dual Tone Multi-Frequency)信令,因其提供更高的拨号速率,迅速取代了传统转盘式电话机使用的拨号脉冲信令.DTMF也应用在交互式控制中,诸如语言菜单.语言邮件. ...

  2. 认识epoll

    linux下的epoll(7)函数,其有着良好的就绪事件通知机制.Epoll 是被linux2.6开始引进的,但是不被其他的类UNIX系统支持,它提供了一种类似select或poll函数的机制:a. ...

  3. Visual Status各个版本官网下载

    网址:https://www.visualstudio.com/zh-hans/vs/older-downloads/

  4. Python3基础 list 使用for循环 删除列表中的重复项

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  5. guulp配置编译ES6

    下面是gulp的配置文件,gulp具体使用点击查看 首先全局安装下 cnpm install gulp -g gulpfile.js  gulp配置文件 var gulp = require(&quo ...

  6. 学习mybatis-3 step by step 篇二

    Mapper XML 文件 基本的*Mapper.xml文件配置就不熬述了具体可参考: http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html 1.sq ...

  7. poj 2186 Popular Cows tarjan

    Popular Cows Description Every cow's dream is to become the most popular cow in the herd. In a herd ...

  8. Python的函数参数传递

    a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun(a) print a # [1]

  9. Springboot mybatis generate 自动生成实体类和Mapper

    https://github.com/JasmineQian/SpringDemo_2019/tree/master/mybatis Springboot让java开发变得方便,Springboot中 ...

  10. CentOS系统-常用组件安装

    1,安装系统后,补装包组yum groupinstall "Compatibility libraries" "Base" "Development ...