poj3278 Catch That Cow

来源:互联网 发布:c语言最长升序片段 编辑:程序博客网 时间:2024/06/06 08:55

本来用DFS做的,总是超时,拿别人AC的程序一测数据结果还一样,但是就是超时,这道题用DFS做要有很多剪枝,不然会有很多的重复,比如第x步走过点m,回溯后再DFS第y步的时候又走过m点,会有大量重复情况,还是BFS比较好剪枝

/*Catch That CowTime Limit: 2000MS      Memory Limit: 65536KTotal Submissions: 63279        Accepted: 19813DescriptionFarmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?InputLine 1: Two space-separated integers: N and KOutputLine 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.Sample Input5 17Sample Output4HintThe fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.*/#include <cstdio>#include <cstring>#include <iostream>#include <cstdlib>#include <limits.h>#include <algorithm>#include <queue>using namespace std;const int maxn = 100010;bool vis[maxn];int sizev = sizeof(vis);int step[maxn];    ///用于记录走过一个点时是第几步queue<int> q;int bfs(int N, int K) {    while (!q.empty()) q.pop();   ///使用前清空队列    q.push(N);    ///将FJ所在的点入队    vis[N] = true;    step[N] = 0;    int head, next;    while (!q.empty()) {    ///队列不为空时BFS        head = q.front();        q.pop();        for (int i = 0; i < 3; i++) {    ///对于三个方向BFS            if (i == 0) {                next = head + 1;            } else if (i == 1) {                next = head - 1;            } else if (i == 2) {                next = head << 1;            }            if (next < 0 || next > 100000 || vis[next]) continue;   ///若越界或以前标记过则continue                                ///其中对vis[next]判断剪枝,用DFS的话似乎不太好标记之前是否重复走过            q.push(next);     ///将新的点入队            vis[next] = true;            step[next] = step[head] + 1;    ///走到next用了step[head] + 1步            if (next == K) return step[next];   ///当走到K时此时step[next]既是最少步数,直接返回        }    }}int main(){    int N, K;    while (~scanf("%d%d", &N, &K)) {        if (N >= K) {              ///若N>=K则只能每次N - 1这样走,所以直接减就行了            printf("%d\n", N - K);            continue;        }        memset(vis, false, sizev);        printf("%d\n", bfs(N, K));    }    return 0;}


0 0
原创粉丝点击