题目大意:
偶像A在(xs, ys)处,她在坐标轴上能活动t秒,每秒她只能往上下左右方向移动一次(不能斜着走)。她的目标去去到目的地。目的地的生成条件是:第0个目的地在 (x0,y0),第i个目的地在(ax⋅xi−1+bx, ay⋅yi−1+by),其中xi−1, yi−1 指的是第i-1个目的地位置的(x,y)。问,偶像A最多能到多少个目的地。
题解:
码这个题时还剩7分钟,因为C题读错了题意导致这个题没有具体看,最后好不容易A了C题,发现这个题其实还是挺简单的,最后慌慌张张地码代码,debug,在最后一分钟交了,没想到竟然过了,真实地体验了一把速度与激情。
其实仔细想来,这个题还是挺有意思的。
首先我们要注意到一个问题,这个点的个数顶多有log2(1e16)个,因为ax>=2,bx>=0,取极限来考虑,当ax=2,bx=0时点是最多的,x0最小为1,因此点数最多为log2(1e16)个,即50多个,这么少的点我们当然可以考虑暴力了。
而且根据样例解释以及坐标为一次函数的性质(
其实主要是根据解释瞎猜),不难想到最优的取法是取一段连续的点。所以我们先求出所有点,然后枚举长度,再判断是否符合条件并更新最大值就行了,类似区间dp的写法。
trick:注意求点时循环的结束条件,以及枚举的最大长度,还有保证数据不溢出就行了。
还是一道很不错的题!!
代码实现:
#pragma GCC optimize(2) #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<cstdio> #include<cstdlib> #include<vector> #include<map> #include<set> #include<stack> #include<queue> #define PI atan(1.0)*4 #define E 2.718281828 #define rp(i,s,t) for (register int i = (s); i <= (t); i++) #define RP(i,t,s) for (register int i = (t); i >= (s); i--) #define ll long long #define ull unsigned long long #define mst(a,b) memset(a,b,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pii pair<int,int> #define mp make_pair #define pb push_back using namespace std; inline int read() { int a=0,b=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') b=-1; c=getchar(); } while(c>='0'&&c<='9') { a=(a<<3)+(a<<1)+c-'0'; c=getchar(); } return a*b; } const ll INF =1e17; struct node{ ll x,y; }p[105]; ll my_abs(ll a){return a>0?a:-a;} ll my_min(ll a,ll b){return a>b?b:a;} ll my_max(ll a,ll b){return a>b?a:b;} int main(){ ll x0,y0,ax,ay,bx,by,xs,ys,t; int num; scanf("%lld%lld%lld%lld%lld%lld",&x0,&y0,&ax,&ay,&bx,&by); scanf("%lld%lld%lld",&xs,&ys,&t); p[0].x=x0,p[0].y=y0; for(num=1;;num++){ if(p[num-1].x>(INF-bx)/ax||p[num-1].y>(INF-by)/ay) break; p[num].x=ax*p[num-1].x+bx; p[num].y=ay*p[num-1].y+by; // if(p[num].x>INF||p[num].y>INF) break; } // rp(i,1,num-1){ // printf("%lld %lld\n",p[i].x,p[i].y); // } int ans=0; rp(i,1,num){ for(int j=0;j+i-1<num;j++){ int k=j+i-1; ll delta=my_abs(p[k].x-p[j].x)+my_abs(p[k].y-p[j].y); delta+=my_min(my_abs(p[k].x-xs)+my_abs(p[k].y-ys),my_abs(p[j].x-xs)+my_abs(p[j].y-ys)); if(delta<=t) ans=my_max(ans,i); } } printf("%d\n",ans); return 0; }