P10217 [省选联考 2024] 季风

P10217 [省选联考 2024] 季风

[省选联考 2024] 季风

题目背景

生活在二维平面的小 X 准备拜访小 Y,但由于气候的变化,平面上刮起了季风。小 X 想知道季风的影响下,TA 至少要多少天能够到达小 Y 的家,但小 X 也是第一次遇见这种怪事,所以请精通算法的你来帮忙。

题目描述

给定 \(n,k,x,y\)\(2n\) 个整数 \(x_0,y_0,x_1,y_1,\dots,x_{n-1},y_{n-1}\)

找到最小的非负整数 \(m\),使得存在 \(2m\) 个实数 \(x_0',y_0',x_1',y_1',\dots,x_{m-1}',y_{m-1}'\) 满足以下条件,或报告不存在这样的 \(m\)

  • \(\sum \limits_{i=0}^{m-1} (x_i'+x_{i \bmod n})=x\)
  • \(\sum \limits_{i=0}^{m-1} (y_i'+y_{i \bmod n})=y\)
  • \(\forall 0\leq i\leq m-1,|x_i'|+|y_i'|\leq k\)

特别地,\(m=0\) 时,认为 \(\sum \limits_{i=0}^{m-1} (x_i'+x_{i \bmod n})\)\(\sum \limits_{i=0}^{m-1} (y_i'+y_{i \bmod n})\) 均为 \(0\)

输入格式

本题有多组测试数据。输入的第一行一个整数 \(T\) 表示测试数据组数。

对于每组测试数据,

  • 第一行四个整数 \(n,k,x,y\)
  • 接下来 \(n\) 行,第 \(i\) 行两个整数 \(x_{i-1},y_{i-1}\)

输出格式

对于每组测试数据输出一行一个整数,如果存在满足题意的 \(m\),输出其最小可能值,否则输出 \(-1\)

欢乐补题捏

首先我们来整理一下式子:
我们将n无限循环,则原式可化为:
$ mx_i'$ =\(x\) - \(\sum \limits_{i=0}^{m-1} x_i\)

$ my_i'$ =\(y\) - \(\sum \limits_{i=0}^{m-1} y_i\)

|\(x\) -
\(\sum \limits_{i=0}^{m-1} x_i\)| +
|\(y\) -
\(\sum \limits_{i=0}^{m-1} y_i\)| \(<=\) \(mk\)

把绝对值拆了之后:

\(\sum \limits_{i=0}^{m-1} (x_i+y_i+k)\) >=\(X+Y\)

\(\sum \limits_{i=0}^{m-1} (x_i-y_i+k)\) >=\(X-Y\)

\(\sum \limits_{i=0}^{m-1} (-x_i+y_i+k)\) >=\(-X+Y\)

\(\sum \limits_{i=0}^{m-1} (-x_i-y_i+k)\) >=\(-X-Y\)

求出同时满足这四个条件的m

\(s_x\)=\(\sum \limits_{i=1}^{x} (x_i+y_i+k)\)
\(sum=s_n\)

考虑枚举每个1<=i<=n:
\(l_i\)为最后一位取在\(i\)时m的下界,\(r_i\)为上界
\((l_i /r_i=X+Y-S_i)/sum\)
\(l_i/r_i\)取决于分母的符号

特殊的,当sum=时,若\(S_i>=X+Y\)则任取,否则不能

同理,对上面提到过的四种情况做相同的讨论,得出\(l,r\)

最后统计答案时,若满足\(l_i<=r_i\)
\(ans=min(ans,l_i*n+i)\)

然后这题就做完了

Code

#include<bits/stdc++.h>
#define int long long
const int N=1e6+5;
const int inf=1e18;
using namespace std;
int x[N],y[N],s[N],l[N],r[N];
int n,k,X,Y;
void calc(int fx,int fy)
{
	int pos=fx*X+fy*Y;
	for(int i=1;i<=n;i++)
	{
		s[i]=s[i-1]+x[i]*fx+y[i]*fy+k;
	}
	if(!s[n])
	{
		for(int i=1;i<=n;i++)
		{
			if(s[i]<pos)r[i]=-1;
		}
		return ;
	}
	else
	{
		for(int i=1,fz,fm=s[n];i<=n;i++)
		{
			fz=pos-s[i];
			if(s[n]>0)
			{
				if(fz>0)//ans_l=(pos-s[i])/s[n] (bigger)
				{
					l[i]=max(l[i],(fz%fm? fz/fm+1 : fz/fm));
				}
			}
			else //ans_r=(pos-s[i])/s[n] (lower)
			{
				if(fz>0)//ans_r<0
				{
					r[i]=-1ll;
				}
				else
				{
					r[i]=min(r[i],fz/fm);
				}
			}
		}
	}
}
void work()
{
	cin>>n>>k>>X>>Y;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&x[i],&y[i]);
		l[i]=0;
		r[i]=inf;
	}
	if(!X&&!Y)
	{
		printf("%lld\n", 0ll);
		return;
	}
	int ans=inf;
	calc(1,1);calc(1,-1);calc(-1,1);calc(-1,-1);
	for(int i=1;i<=n;i++)
	{
		if(l[i]<=r[i])
		ans=min(ans,l[i]*n+i);
	}
	printf("%lld\n",ans==inf? -1ll : ans);
}
#undef int 
int main()
{
	//freopen("P10217_1.in","r",stdin);//freopen("P10217.out","w",stdout);
	int T;
	cin>>T;
	while(T--)
	{
		work();
	}
}
posted @ 2024-12-06 11:47  liuboom  阅读(14)  评论(0)    收藏  举报