Problem A 夏洛特
若当前处在点$(x,y)$下一时刻可以向该点四周任意方向走动一步,
初始在$(0,0)$是否存在一条合法的路线满足下列$n$个限制:
每一个限制形如$t_i , x_i , y_i$表示第$t_i$时刻,需要在点$(x_i , y_i)$ 处
输出"YES"或者"NO",有$T(T\leq 10)$组数据。
对于$100\%$的数据满足$n \leq 10^5 ,0 \leq x_i,y_i \leq 10^5 , 0 \leq t_i \leq 10^7$
Sol: 首先按照时间先后排序,每次考虑从$t_0 , x_0 ,y_0$的限制走到$t , x, y$的限制、
显然,从$(x_0,y_0)$走到$(x,y)$至少需要$|x-x_0|+|y-y_0|$步,
于是令$res = t - t_0 - (|x-x_0|+|y-y_0|)$ 表示剩余需要浪费的步数。
显然,如果剩余步数为偶数那么可以上下、上下的构造出合法解,若剩余步数为奇数则没有办法构造。
上述算法的复杂度是$O(T n \ log_2 n)$
# include <bits/stdc++.h> # define int long long using namespace std; const int N=2e5+10; struct rec{ int t,x,y; }a[N]; int n; bool cmp(rec a,rec b){return a.t<b.t;} bool work() { int t=0ll,x=0ll,y=0ll; for (int i=1;i<=n;i++) { int res=a[i].t-t-abs(a[i].x-x)-abs(a[i].y-y); if ((res < 0ll) || (res & 1ll)) return false; t=a[i].t; x=a[i].x; y=a[i].y; } return true; } inline int read() { int X=0,w=0; char c=0; while(c<'0'||c>'9') {w|=c=='-';c=getchar();} while(c>='0'&&c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar(); return w?-X:X; } signed main() { freopen("charlotte.in","r",stdin); freopen("charlotte.out","w",stdout); int T=read(); while (T--) { n=read(); for (int i=1;i<=n;i++) a[i].t=read(),a[i].x=read(),a[i].y=read(); sort(a+1,a+1+n,cmp); puts(work()?"Yes":"No"); } return 0; }