花了2个多小时debug. 难受, 想哭.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <utility>
#include <queue>
#include <cmath>
#include <algorithm>
#include <cstring>
#define MAX (5+1)
#define valid(x,y) (1<=x&&x<=N && 1<=y&&y<=M)
using namespace std;
int N, M, T;
bool a[MAX][MAX];
bool vis[MAX][MAX];
//typedef pair<int,int> xy;
struct xy {
int x;
int y;
bool* vis;
xy()= default;
xy(int x_, int y_, bool* vis_):x(x_),y(y_){
vis=vis_;
}
};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int bfs(int sx,int sy, int fx, int fy) {
queue<xy> q;
// vis[sx][sy]=true; // 为什么多次一句要vis?因为不想初始化
bool tmp_mem[MAX*MAX];
memcpy(tmp_mem,vis, sizeof(tmp_mem));
tmp_mem[sx*MAX+sy]=true;
q.push(xy(sx,sy,tmp_mem));
xy tmp; // 用在后面
int tmp_x, tmp_y; // 用在后面
int ans=0;
while(!q.empty()) {
tmp=q.front();
q.pop();
if(tmp.x==fx&&tmp.y==fy) {
++ans;
continue;
}
for(int i = 0; i < 4; i++) {
tmp_x=tmp.x+dx[i];
tmp_y=tmp.y+dy[i];
if(valid(tmp_x, tmp_y)&&!a[tmp_x][tmp_y]&&!tmp.vis[tmp_x*MAX+tmp_y]) {
bool tmp_mem_in[MAX*MAX];
memcpy(tmp_mem_in,tmp.vis,sizeof(tmp_mem_in));
tmp_mem_in[tmp_x*MAX+tmp_y]=true;
q.push(xy(tmp_x,tmp_y,tmp_mem_in));
printf("qsize:%d
",q.size());
}
}
}
return ans;
}
int main() {
freopen("../IO/input.txt","r",stdin);
int SX, SY, FX, FY;
scanf("%d %d %d", &N, &M, &T);
scanf("%d %d %d %d", &SX, &SY, &FX, &FY);
int tmp_x, tmp_y;
for (int i = 0; i < T; ++i) {
scanf("%d %d", &tmp_x, &tmp_y);
a[tmp_x][tmp_y]=true;
}
printf("%d", bfs(SX,SY,FX,FY));
}
这个对应的题目是, P1605.
给的输入是:
2 2 0
1 1 2 2
发现输出为1, 本来应该为2.
然后就单步调试.
发现诡异的事:
扩展节点(2,1), 放进去的时候, tmp_mem_in[13]=true
. 但是当它被取出来的时候, tmp_mem_in[13]
变成了false
. 我感到震惊. 震惊了大概半个多小时, 怀疑这是queue实现的bug.
结果问题出在: 虽然是个数组, 但是bool tmp_mem_in[MAX*MAX];
, 它是局部变量, 离开循环就被释放掉了!
启示: 不要在可见的局部空间试图开辟malloc, new以外的内存, 不会起作用的! 哪怕传给一个作用域更大的指针, 也毫无用处!