1 条题解

  • 0
    @ 2022-6-19 21:45:06
    #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
    上传者