[Luogu P1588]丢失的牛
本题抽象一下就是从一个点出发,然后经过坐标x2或+1或-1到另一个点。显然这就是一个搜索题,而且显然可以看出步数最多就是两个点坐标之差。但是数据范围105,直接暴搜肯定要么MLE要么TLE,肯定不行,一定要加上优化。
我们注意到坐标的范围是(0,105],那么如果一个点扩展到了这个范围之外显然就不可能得到解了,因此直接剪枝。同时我们用bfs搜索,显然第一次搜到某个点那一定是到这个点的最少步数,之后再到达这个点就没必要再搜一遍了,有些记忆化的思想。
所以最后一顿剪枝操作就可以通过本题了,模拟的时候就因为剪枝条件少了一个导致MLEqwq。
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<queue> using namespace std; int d[100010]; bool check(int x) { return x > 0 && x < 100000 && !d[x]; } int s,t; struct qwq { int x,step; }top; void bfs() { queue<qwq>q; q.push((qwq){s,1}); d[s] = 1; while(q.size()) { top = q.front(); q.pop(); if(top.x == t) return; if(check(top.x + 1)) { q.push((qwq){top.x + 1,top.step + 1}); d[top.x + 1] = top.step + 1; } if(check(top.x - 1)) { q.push((qwq){top.x - 1,top.step + 1}); d[top.x - 1] = top.step + 1; } if(check(top.x << 1)) { q.push((qwq){top.x << 1,top.step + 1}); d[top.x << 1] = top.step + 1; } } } int main() { int tt; scanf("%d",&tt); while(tt--) { scanf("%d%d",&s,&t); memset(d,0,sizeof(d)); bfs(); printf("%d\n",d[t] - 1); } return 0; }