1 条题解
-
0
#include<map> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; template<class AC>void r(AC &x){ x=0; int f=0; char ch=getchar(); while(ch<'0'||ch>'9'){ f|=(ch=='-'); ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } x=f?-x:x; return; }//头文件&&快读 struct AC{ int sum,x,y;//x,y坐标和走到这一步的最小步数sum bool a,b,c,d,e,f,g,h;//确定8方向可不可以走 }k; queue<AC>q;//队列,就一个,没错,你没有眼花 int n,m,a[1005][1005],v[1005][1005][10];//vis数组3维,前面说过了 bool check(int x,int y){//判断有没有越界 if(x>n||x<1||y>m||y<1)return 0; return 1; } int main(){ r(n);r(m); swap(n,m);//本人习惯n在前,m在后,可以无视 for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)r(a[i][j]);//读入(快读大法好) q.push(AC{0,1,1,1,1,1,1,1,1,1,1});//(1,1)所需步数:0,能向8个方向任意出发 /* q.push(AC{1,0})PS:AC是结构体名 等同于 AC x; x.x=1,x.y=0; q.push(x); 由于本题作者笨拙,用了11个变量 所以这样写无法避免冗长的码量 降低可读性 故此这样写 有warning不用管 */ while(!q.empty()){//BFS老套路,队列非空 k=q.front();q.pop();//取队首 /* 下面的内容我写复杂了 其实没有那个必要 不过这样写通俗易懂 走8个方向后的坐标怎么求不用多说 先调用check函数判断是否越界 然后判断vis数组,走不同的方向第3维就不同 举例: 假设下一个点可以走到(3,3),是横着走过来的 那么判断v[3][3][1]是否为0就可以了 最后还要满足不能走同一方向的条件 同时满足的话,这个点的步数为取的队首元素的步数+1(这不用解释的吧) 同时,这个点就不能走对应方向了,置0 如果到达终点,直接输出 下面的内容就是我如上所说,代码是长了点 但是每个方向的枚举看的十分条理清晰 */ if(check(k.x+a[k.x][k.y],k.y)&&!v[k.x+a[k.x][k.y]][k.y][1]&&k.a==1){ q.push(AC{k.sum+1,k.x+a[k.x][k.y],k.y,0,1,1,1,1,1,1,1}); v[k.x+a[k.x][k.y]][k.y][1]=1; if(k.x+a[k.x][k.y]==n&&k.y==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x-a[k.x][k.y],k.y)&&!v[k.x-a[k.x][k.y]][k.y][2]&&k.b==1){ q.push(AC{k.sum+1,k.x-a[k.x][k.y],k.y,1,0,1,1,1,1,1,1}); v[k.x-a[k.x][k.y]][k.y][2]=1; if(k.x-a[k.x][k.y]==n&&k.y==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x,k.y+a[k.x][k.y])&&!v[k.x][k.y+a[k.x][k.y]][3]&&k.c==1){ q.push(AC{k.sum+1,k.x,k.y+a[k.x][k.y],1,1,0,1,1,1,1,1}); v[k.x][k.y+a[k.x][k.y]][3]=1; if(k.x==n&&k.y+a[k.x][k.y]==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x,k.y-a[k.x][k.y])&&!v[k.x][k.y-a[k.x][k.y]][4]&&k.d==1){ q.push(AC{k.sum+1,k.x,k.y-a[k.x][k.y],1,1,1,0,1,1,1,1}); v[k.x][k.y-a[k.x][k.y]][4]=1; if(k.x==n&&k.y-a[k.x][k.y]==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x+a[k.x][k.y],k.y+a[k.x][k.y])&&!v[k.x+a[k.x][k.y]][k.y+a[k.x][k.y]][5]&&k.e==1){ q.push(AC{k.sum+1,k.x+a[k.x][k.y],k.y+a[k.x][k.y],1,1,1,1,0,1,1,1}); v[k.x+a[k.x][k.y]][k.y+a[k.x][k.y]][5]=1; if(k.x+a[k.x][k.y]==n&&k.y+a[k.x][k.y]==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x+a[k.x][k.y],k.y-a[k.x][k.y])&&!v[k.x+a[k.x][k.y]][k.y-a[k.x][k.y]][6]&&k.f==1){ q.push(AC{k.sum+1,k.x+a[k.x][k.y],k.y-a[k.x][k.y],1,1,1,1,1,0,1,1}); v[k.x+a[k.x][k.y]][k.y-a[k.x][k.y]][6]=1; if(k.x+a[k.x][k.y]==n&&k.y-a[k.x][k.y]==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x-a[k.x][k.y],k.y+a[k.x][k.y])&&!v[k.x-a[k.x][k.y]][k.y+a[k.x][k.y]][7]&&k.g==1){ q.push(AC{k.sum+1,k.x-a[k.x][k.y],k.y+a[k.x][k.y],1,1,1,1,1,1,0,1}); v[k.x-a[k.x][k.y]][k.y+a[k.x][k.y]][7]=1; if(k.x-a[k.x][k.y]==n&&k.y+a[k.x][k.y]==m){ printf("%d\n",k.sum+1); return 0; } } if(check(k.x-a[k.x][k.y],k.y-a[k.x][k.y])&&!v[k.x-a[k.x][k.y]][k.y-a[k.x][k.y]][8]&&k.h==1){ q.push(AC{k.sum+1,k.x-a[k.x][k.y],k.y-a[k.x][k.y],1,1,1,1,1,1,1,0}); v[k.x-a[k.x][k.y]][k.y-a[k.x][k.y]][8]=1; if(k.x-a[k.x][k.y]==n&&k.y-a[k.x][k.y]==m){ printf("%d\n",k.sum+1); return 0; } }//8个方向的枚举结束 } puts("NEVER");//如果不能到达,输出"NEVER" return 0; }
- 1
信息
- ID
- 302
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者