每日一题-24-06-17 (P10217)

今年省选题,考场上竟然没做出来

今天似乎直接一眼出来了

就是枚举下 \(m\)\(n\) 的余数

然后解个方程即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int T,n,X,Y;
int x[100005],y[100005];
ll s[100005],t[100005],res,k;
ll sub_down(ll x,ll y){
	if(x<0)x=-x,y=-y;
	if(y>0)return x/y;
	else return -((x-y-1)/(-y));
}
ll sub_up(ll x,ll y){
	if(x<0)x=-x,y=-y;
	if(y>0)return (x+y-1)/y;
	else return -(x/(-y));
}
int main(){
	scanf("%d",&T);
	while(T--){
		res=1e18;
		scanf("%d%lld%d%d",&n,&k,&X,&Y);
		for(int i=1;i<=n;i++){
			scanf("%d%d",&x[i],&y[i]);
			s[i]=s[i-1]+x[i]+y[i];
			t[i]=t[i-1]+x[i]-y[i];
		}
		for(ll q=0;q<n;q++){
			//m=p*n+q
			ll lp=0,rp=1e18;
			if(s[n]>n*k)rp=min(rp,sub_down(X+Y+q*k-s[q],s[n]-n*k));
			else if(s[n]<n*k)lp=max(lp,sub_up(X+Y+q*k-s[q],s[n]-n*k));
			else if(X+Y+q*k-s[q]<0)continue;
			if(n*k+s[n]>0)lp=max(lp,sub_up(X+Y-s[q]-q*k,n*k+s[n]));
			else if(n*k+s[n]<0)rp=min(rp,sub_down(X+Y-s[q]-q*k,n*k+s[n]));
			else if(X+Y-s[q]-q*k>0)continue;
			if(t[n]>n*k)rp=min(rp,sub_down(X-Y+q*k-t[q],t[n]-n*k));
			else if(t[n]<n*k)lp=max(lp,sub_up(X-Y+q*k-t[q],t[n]-n*k));
			else if(X-Y+q*k-t[q]<0)continue;
			if(n*k+t[n]>0)lp=max(lp,sub_up(X-Y-t[q]-q*k,n*k+t[n]));
			else if(n*k+t[n]<0)rp=min(rp,sub_down(X-Y-t[q]-q*k,n*k+t[n]));
			else if(X-Y-t[q]-q*k>0)continue;
			if(lp<=rp)res=min(res,lp*n+q);
		}
		if(res!=1e18)printf("%lld\n",res);
		else puts("-1");
	}
	return 0;
}

感觉挺简单的(考场竟然不会,感觉自己是废物)

就是那个带负数的上下取整写的有点烂(还在那里WA了一发)

posted @ 2024-06-17 20:55  Kent530  阅读(6)  评论(0编辑  收藏  举报