GDOI2016模拟8.15送票
2015-08-15 22:05
316 查看
题目
Mirko准备带他所有的朋友去Zaz演唱会。他已经拿到了票,现在在回去派送门票的路上。
Mirko朋友的住所都可以用直角坐标系来表示。他在走路的时候,只能经过整数坐标点。他走一步可以移动到相邻的八个整数坐标点(上,下,左,右,上左,下左,上右,下右)。
Mirko的每个朋友住在一些整数坐标点(x,y)上,而且愿意走一段距离去见Mirko。具体来说,Mirko可以在离他朋友家里不超过P步的地方见他的朋友,P取决于他朋友的慵懒程度。
当他完成派送门票的事后,Mirko回想起了他见朋友的顺序。计算Mirko在这段路上走的最少可能的步数。Mirko的起始点和终止点是未知的。
显然,这题时切比雪夫距离,第i个朋友的覆盖范围是一个len*2为边长的矩形。
这题我们可以没必要知道起点和终点的具体位置,但可以知道最短距离能到达的位置的集合。
举例来说,就是我们现在位于一个矩形内(表示通过最短距离到第i个矩阵内的终点集合S),那么现在我们要到i+1个矩形内,那么我们只需知道S最少走L步能与第i+1个矩形相交,那么答案就加上L(这个可以二分,也可以直接几个if判断一下)(因为我们不必知道它走到哪里,只需知道他能走最少步数走到哪里)然后求交的出新的终点集合S
贴代码
Mirko准备带他所有的朋友去Zaz演唱会。他已经拿到了票,现在在回去派送门票的路上。
Mirko朋友的住所都可以用直角坐标系来表示。他在走路的时候,只能经过整数坐标点。他走一步可以移动到相邻的八个整数坐标点(上,下,左,右,上左,下左,上右,下右)。
Mirko的每个朋友住在一些整数坐标点(x,y)上,而且愿意走一段距离去见Mirko。具体来说,Mirko可以在离他朋友家里不超过P步的地方见他的朋友,P取决于他朋友的慵懒程度。
当他完成派送门票的事后,Mirko回想起了他见朋友的顺序。计算Mirko在这段路上走的最少可能的步数。Mirko的起始点和终止点是未知的。
显然,这题时切比雪夫距离,第i个朋友的覆盖范围是一个len*2为边长的矩形。
这题我们可以没必要知道起点和终点的具体位置,但可以知道最短距离能到达的位置的集合。
举例来说,就是我们现在位于一个矩形内(表示通过最短距离到第i个矩阵内的终点集合S),那么现在我们要到i+1个矩形内,那么我们只需知道S最少走L步能与第i+1个矩形相交,那么答案就加上L(这个可以二分,也可以直接几个if判断一下)(因为我们不必知道它走到哪里,只需知道他能走最少步数走到哪里)然后求交的出新的终点集合S
贴代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #define N 200001 using namespace std; int n; long long ans; struct node{ long long x1,y1,x2,y2; }s,a; node expand(node a,long long b){ a.x1-=b,a.y1-=b; a.x2+=b,a.y2+=b; return a; } node jiao(node a,node b){ a.x1=max(a.x1,b.x1); a.x2=min(a.x2,b.x2); a.y1=max(a.y1,b.y1); a.y2=min(a.y2,b.y2); return a; } bool in(node a,long long x,long long y){ return a.x1<=x&&x<=a.x2&&a.y1<=y&&y<=a.y2; } bool jian1(node a,node b){ return in(a,b.x1,b.y1)&&in(a,b.x1,b.y2)&&in(a,b.x2,b.y1)&&in(a,b.x2,b.y2); } bool jian(node a,node b){ static node c; c=jiao(a,b); return jian1(b,c)&&jian1(b,c); } int er(node a,node b){ static long long l,r,mid; l=0; r=200000000; while (l<=r) if (jian(expand(a,mid=(l+r)/2),b))r=mid-1;else l=mid+1; if (l<0)l=0; while (l&&jian(expand(a,l-1),b))l--; while (!jian(expand(a,l),b))l++; return l; } void init(){ static int x,y,p,len; scanf("%d",&n); scanf("%d %d %d",&x,&y,&p); s.x1=x-p,s.x2=x+p; s.y1=y-p,s.y2=y+p; for (int i=2;i<=n;i++){ scanf("%d %d %d",&x,&y,&p); a.x1=x-p,a.x2=x+p; a.y1=y-p,a.y2=y+p; len=er(s,a); s=jiao(expand(s,len),a); ans+=len; } } void write(){ printf("%lld",ans); } int main(){ init(); write(); return 0; }
相关文章推荐
- C语言一维数组复制
- 失忆
- 关于PCI,PCI-X,PCI-E等总线的实际传输速率
- 鸡蛋十种吃法八种错
- ubuntu 下安装 lxml 失败
- ZOJ3080 ChiBi (最短路)
- HDU 1978 How many ways
- 单文档、多文档浅析
- Linux 线程同步(一)
- ZOJ3080 ChiBi (最短路)
- 【CCF系列】有趣的数
- HTML常用标签和属性
- 使用rundll32.exe运行dll函数
- Markdown使用方法
- Minimum Depth of Binary Tree
- HIbernate关系映射--单向一对多@OneToMany
- The Tree |
- PAT 1080. Graduate Admission (30)
- facl:文件访问控制列表
- myeclipse 查找文件(open type)快捷键