Codeforces Round614 D 题——暴力+构造

题目链接:https://codeforces.com/contest/1293/problem/D

题目大意:

偶像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:注意求点时循环的结束条件,以及枚举的最大长度,还有保证数据不溢出就行了。

还是一道很不错的题!!

扫描二维码关注公众号,回复: 9917656 查看本文章

代码实现:

#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;
}
发布了342 篇原创文章 · 获赞 220 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43472263/article/details/104163822
今日推荐