poj 3278

来源:互联网 发布:订阅 sql server 时间 编辑:程序博客网 时间:2024/05/21 09:35

背景:开始wa了几次,是因为剪枝的不合理。然后去掉其中几个错误剪枝ac。就是三个方向的bfs,一定要用标记数组,要不然数据会呈现3的指数级别增长会爆队列的。这里标记数组起始可以用bool visit[M]。

学习:1.如果队列不用stl的话,可以用数组实现,只是在数组中间操作:

int queue[2*M];int *front=queue+M,*back=queue+M+1;    //定义队列的首尾指针
我的代码:

#include<map>#include<set>#include<stack>#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#define M 200009#define INF 100000000#define LL long long intusing namespace std;int vis[M],n,m,dir[3][2]={1,-1,1,1,2,0};struct place{int x,count;}temp1,temp2;void bfs(void){     if(n > m){n-=m;return;}     queue<place> q;     temp1.x=n;     temp1.count=0;     q.push(temp1);     while(!q.empty()){        temp1=q.front();        vis[temp1.x]=0;        q.pop();        if(temp1.x == m){n=temp1.count;return;}        for(int i=0;i < 3;i++){            temp2.x=temp1.x*dir[i][0]+dir[i][1];            if(i == 2 && temp1.x > m) continue;    //剪枝            if(temp2.x >= 0 && temp2.x <= M && vis[temp2.x]){                temp2.count=temp1.count+1;                q.push(temp2);            }        }     }     return;}int main(void){    while(~scanf("%d%d",&n,&m)){        memset(vis,1,sizeof(vis));        bfs();        printf("%d\n",n);    }    return 0;}

0 0
原创粉丝点击