codeforces 1292B

题目链接

题意

有一些标记点,其中每个点都是上一个点根据一定的规律变化而来的:
x i = x i 1 a x + b x , y i = y i 1 a y + b y x_i=x_{i-1}*ax+bx,y_i=y_{i-1}*ay+by
给一个起点,每一个时刻可以想上下左右中的一个方向移动一步,给出总时间t,问最多可以经过几个标记点。

数据范围

2 a x , a y 100 , 1 b x , b y , t , 1 0 16 2\le a_x,a_y\le 100,1\le b_x,b_y,t,起点坐标\le 10^{16}

解法

首先考场上以为 a x , a y a_x,a_y 可以等于1,浪费了很多时间。。。
观察之后可以发现有效的标记点数量不会很多,所以就暴力处理出有多少标记点会有作用,然后枚举先从起点到哪个标记点,然后枚举向左还是向右走,就结束了。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e16;
inline int read(){
	char c=getchar();int t=0,f=1;
	while((!isdigit(c))&&(c!=EOF)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)&&(c!=EOF)){t=(t*10)+(c^48);c=getchar();}
	return t*f;
}
int x0,y0,ax,ay,bx,by,xs,ys,t;
int prex[105],prey[105];
signed main(){
	//freopen("2.in","r",stdin);
	//freopen("2.out","w",stdout);
	x0=read(),y0=read(),ax=read(),ay=read(),bx=read(),by=read();
	xs=read(),ys=read(),t=read();
		int an=0;
		prex[0]=x0;prey[0]=y0;
		for(long long i=1;i<=100;i++){
			prex[i]=prex[i-1]*ax+bx;
			prey[i]=prey[i-1]*ay+by;
			if(prex[i]+prey[i]>maxn*4||prex[i]<0||prey[i]<0)break;
		}
		for(long long i=0;i<=100;i++){
			if(prex[i]+prey[i]>maxn*4||prex[i]<0||prey[i]<0)break;
			int rest=t-abs(prex[i]-xs)-abs(prey[i]-ys);
			//printf("%lld %lld %lld %lld\n",i,prex[i],prey[i],rest);
			if(rest<0)continue;
			for(long long j=0;j<=100;j++){	
				if(prex[j]+prey[j]>maxn*4||prex[j]<0||prey[j]<0)break;
				if(abs(prex[i]-prex[j])+abs(prey[i]-prey[j])<=rest){
					an=max(an,abs(j-i)+1);
				}
			}
		}
		printf("%lld\n",an);
	return 0;
}
 

发布了95 篇原创文章 · 获赞 9 · 访问量 3196

猜你喜欢

转载自blog.csdn.net/wmhtxdy/article/details/104067633