背景:开始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 int
using 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;
}