CF614 - Div. 1 Aroma's Search

一道蛮简单的思维题。

容易发现点数是 \(\log\) 级别的,不超过60个。并且先往 \((x_0, y_0)\) 方向走一定比先往 \((x_{+\infty}, y_{+\infty})\) 方向更优。(可以用类似等比数列求前缀和的方式证得)。

要进行的操作是先走到一个点 \((x_i, y_i)\),再进行上面的操作。(注意不能从起点直接往 \(0\) 跳,因为此时不一定更优,必须要也从特殊点往 \(0\) 跳才一定是更优的,所以需要枚举这个真正的起点)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
//#define int ll
using namespace std;
using ll = long long;
const int N = 65;
const ll inf = 2e16;
struct node{
	ll x, y;
}st, c[N];
ll getdis(node a, node b){
	return abs(a.x - b.x) + abs(a.y - b.y);
}
ll ax, ay, bx, by, t;
int ans = 0;
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> c[0].x >> c[0].y >> ax >> ay >> bx >> by;
	cin >> st.x >> st.y >> t;
	int maxn = 0;
	while(getdis(c[maxn], st) <= inf){
		++ maxn;
		c[maxn].x = ax * c[maxn - 1].x + bx, c[maxn].y = ay * c[maxn - 1].y + by;		
	}
	F(i, 0, maxn){
		int sm = 0;
		ll tt = t;
		if(getdis(c[i], st) <= tt) tt -= getdis(c[i], st), ++ sm;
		else continue;
		G(j, i - 1, 0){
			if(getdis(c[j], c[j + 1]) <= tt) tt -= getdis(c[j], c[j + 1]), ++ sm;
			else break;
		}
		F(j, 1, maxn) if(getdis(c[j], c[j - 1]) <= tt) tt -= getdis(c[j], c[j - 1]), sm += (j > i); 
		ans = max(ans, sm);
	}
	cout << ans << '\n';
	return 0;
}
posted @ 2025-02-07 15:15  superl61  阅读(11)  评论(0)    收藏  举报