首页 > 其他分享 >CF1979E Manhattan Triangle

CF1979E Manhattan Triangle

时间:2024-06-24 11:54:22浏览次数:3  
标签:tmp 10 return int t2 printf CF1979E Triangle Manhattan

题目描述

给定\(n\)个点,找出三个点使得这三个点两两之间的曼哈顿距离为偶数\(d\)

\[n\le 300000 \]

题解

与一个点的曼哈顿距离为\(d\)的点是一个斜\(45°\)的正方形
设这个点坐标为\((x,y)\)
考虑另外两个点可能在哪些位置,
如果另外两个点在正方形的同一条边上,那么这两个点的横纵坐标的差的绝对值一定都等于\(d/2\),即满足\(|x_1-x_2|=d/2,|y_1-y_2|=d/2\)
如果不在同一条边上,那么一定有一个点与\((x,y)\)满足\(|x_1-x|=d/2,|y_1-y|=d/2\)
也就是说如果可以找到三个点满足两两之间的曼哈顿距离为偶数\(d\),那么这三个点中一定存在两个点满足\(|x_1-x_2|=d/2,|y_1-y_2|=d/2\)
那么做法就很简单了,枚举其中一个点,判断是否存在另一个点满足\(|x_1-x_2|=d/2,|y_1-y_2|=d/2\),这个可以用\(map\)判断,然后就是找到一个在这两个点的正方形的交集上的点,交集其实就是两条线段,可以预处理排序后用二分判断,具体可以看代码
时间复杂度\(O(n\log n)\)

\(\text{code}\)

#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
const int N=1e6+1000,M=4e5,inf=1e9+10;
int n,d,a[N+10],b[N+10];
struct node
{
	int x,y;
}p[N+10];
map<pair<int,int>,int> t;
vector<int> t1[N+10],t2[N+10];
bool cmp(int a,int b){return p[a].x<p[b].x;}
int check(int x1,int y1,int x2,int y2)
{
	int c=0;
	if(y1-x1==y2-x2)
	{
		c=y1-x1+M;
		if(t1[c].size()==0) return false;
		int l=0,r=t1[c].size()-1,ans=-1;
		for(int mid;l<=r;)
		{
			mid=l+r>>1;
			if(p[t1[c][mid]].x<=x2) ans=mid,l=mid+1;
			else r=mid-1;
		}
		if(ans==-1) return 0;
		if(p[t1[c][ans]].x>=x1) return t1[c][ans];
		else return 0;
	}
	else
	{
		c=x1+y1+M;
		if(t2[c].size()==0) return false;
		int l=0,r=t2[c].size()-1,ans=-1;
		for(int mid;l<=r;)
		{
			mid=l+r>>1;
			if(p[t2[c][mid]].x<=x2) ans=mid,l=mid+1;
			else r=mid-1;
		}
		if(ans==-1) return 0;
		if(p[t2[c][ans]].x>=x1) return t2[c][ans];
		else return 0;
	}
	return 0;
}
void solve()
{
	for(int i=1,tmp;i<=n;i++)
	{
		int x=p[i].x,y=p[i].y,k=d>>1;
		if(t.find({x-k,y-k})!=t.end())
		{
			tmp=check(x-d,y,x-k,y+k);
			if(tmp)
			{
//				puts("fuc");
//				printf("%d %d %d\n",x,y,k);
//				printf("%d %d\n",p[t[{x-k,y-k}]].x,p[t[{x-k,y-k}]].y);
				printf("%d %d %d",i,t[{x-k,y-k}],tmp);
				return;
			}
			tmp=check(x,y-d,x+k,y-k);
			if(tmp)
			{
				printf("%d %d %d",i,t[{x-k,y-k}],tmp);
				return;
			}
		}
		if(t.find({x-k,y+k})!=t.end())
		{
			tmp=check(x-d,y,x-k,y-k);
			if(tmp)
			{
				printf("%d %d %d",i,t[{x-k,y+k}],tmp);
				return;
			}
			tmp=check(x,y+d,x+k,y+k);
			if(tmp)
			{
				printf("%d %d %d",i,t[{x-k,y+k}],tmp);
				return;
			}
		}
	}
	printf("0 0 0");
}
int main()
{
//	freopen("e.in","r",stdin);
	int T;
	scanf("%d",&T);
	for(;T--;)
	{
		scanf("%d %d",&n,&d);
		for(int i=1;i<=n;i++) scanf("%d %d",&p[i].x,&p[i].y),t[{p[i].x,p[i].y}]=i;
		for(int i=1;i<=n;i++)
		{
			t1[p[i].y-p[i].x+M].push_back(i),a[i]=p[i].y-p[i].x+M;
			t2[p[i].y+p[i].x+M].push_back(i),b[i]=p[i].y+p[i].x+M;
		}
		sort(a+1,a+1+n),sort(b+1,b+1+n);
		for(int i=1;i<=n;i++)
			if(a[i]!=a[i-1])
				sort(t1[a[i]].begin(),t1[a[i]].end(),cmp);
		for(int i=1;i<=n;i++)
			if(b[i]!=b[i-1])
				sort(t2[b[i]].begin(),t2[b[i]].end(),cmp);
		solve(),puts("");
		for(int i=1;i<=n;i++) t1[a[i]].clear();
		for(int i=1;i<=n;i++) t2[b[i]].clear();
		t.clear();
	}
	return 0;
}

标签:tmp,10,return,int,t2,printf,CF1979E,Triangle,Manhattan
From: https://www.cnblogs.com/the-blog-of-doctorZ/p/18264730

相关文章

  • LeetCode //C - 119. Pascal‘s Triangle II
    119.Pascal’sTriangleIIGivenanintegerrowIndex,returntherowIndexth(0-indexed)rowofthePascal’striangle.InPascal’striangle,eachnumberisthesumofthetwonumbersdirectlyaboveitasshown: Example1:Input:rowIndex=3Outpu......
  • Games101-3 triangle
    rasterize==drawingontothescreencolor=(red,green,blue)pixelindicesarefrom(0,0)to(width-1,height-1)pixel(x,y)iscenteredat(x+0.5,y+0.5)光栅化判断一个像素的中心点是否需要draw采样的方法--将函数离散化如果中心再三角形内。如何判断......
  • AoPS - Chapter 3 More Triangles
    本章主要讲解正弦定理、余弦定理、海伦公式、Stewart'sTheorem。本文在没有特殊说明时,默认在\(\triangleABC\)中:\(a\)为角\(A\)对边,\(b\)为角\(B\)对边,\(c\)为角\(C\)对边。\(r\)为内切圆半径(inradius),\(R\)为外接圆半径(circumradius)。\([ABC]\)为\(\triangl......
  • 题解:CF1337A Ichihime and Triangle
    看到大佬们基本都是直接输出\(b\)\(c\)\(c\)了事儿,一身反骨有其它构造方法的我表示不服,遂作此篇。众所周知,两边之和大于第三边,所以,如果\(b+c>d\),那么\(b\)、\(c\)、\(d\)就是正确的。那如果不满足呢?在题目条件下\(b+c>b+c-1\),那么这一组就是合理的。分别验......
  • 【计算几何】Triangle Cillision 三角碰撞 [模型转化][二分]
    题意给定一个边长为L的三角形和一个直径非常微小的球,问球在三角形内与三角形的边第k次碰撞的时间思路模型转化:将碰撞转化为穿越二分查找时间code:#include<bits/stdc++.h>usingnamespacestd;constdoubleeps=1e-7;#defineendl"\n"#defineintlonglongstructPoi......
  • P4423 / YC271A [ 20240411 CQYC省选模拟赛 T1 ] 三角形(triangle)
    题意给定\(n\)个点,求平面最小三角形周长。Sol其实挺简单一算法,一直没学。先随机转个∠,然后按照\(x\)排序。考虑分治。注意到分治左右两边的答案对当前可用的区间有限制。将满足限制的点按照\(y\)排序。这里可以归并做到一只\(log\)。然后集中注意力,发现对于每个点......
  • 洛谷题单指南-动态规划1-P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles
    原题链接:https://www.luogu.com.cn/problem/P1216题意解读:计算数字三角形最高点到最后一行路径之和最大值,典型线性DP。解题思路:设a[i][j]表示数字三角形的值,设dp[i][j]表示从最高点到第i行第j列路径之和的最大值,由于每一步可以走到左下方的点也可以到达右下方的点,所以dp[i][......
  • M. Triangle Construction
    原题链接题解如果存在某一条边的\(a_i>=2*(sum-a_i)\)那么这条边一定有点剩余无法连接,为什么?这条边上每取两个点作为底边点,就一定能去外面一个点作为顶点,且无交叉(顺时针或逆时针)code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;intmain(){ll......
  • P4139TriangleXor
    数学#计数#容斥分为\(4\)个部分计算上面的按奇偶性分类下面的按每一层容斥,即\(siz_i-2\timessiz_{i-1}+siz_{i-2}\)左右直接对每一块计算面积//Author:xiaruizeconstintINF=0x3f3f3f3f3f3f3f3f;constintMOD=1000000007;constintN=2e5+10;intn;......
  • Lecture 05 Rasterization 1(Triangles)
    Lecture05Rasterization1(Triangles)什么是屏幕一组像素数组的大小:分辨率一种典型的光栅成像设备光栅光栅化==画在屏幕离像素一个个小方块,每个方块中的颜色不会变化(实际上不准确,这样描述只是方便理解)颜色是RGB三个值的混合定义屏幕空间像素的坐标写成\((x,......