codeforce contest 877D搜索
这道题运用 二进制模拟方向状态
开始以为每次走一步情况很多,用优先队列写的,都来发现别人直接枚举方向,次数,用二进制记录就行了
mark一下
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<string> using namespace std; #define maxn 1005 #define MST(vis,x) memset(vis,x,sizeof(vis)) #define ll long long char s1[maxn][maxn]; int n,m,k; struct Node { int x,y; }; int ma[4][2]={-1,0,1,0,0,-1,0,1}; int vis[maxn][maxn]; int dis[maxn][maxn]; bool check(int x,int y) { if(x<=n&&x>=1&&y<=m&&y>=1)return true; else return false; } void bfs(int x1,int y1,int x2,int y2) { MST(vis,0); MST(dis,0); queue<Node>q; Node temp; temp.x=x1; temp.y=y1; q.push(temp); vis[x1][y1]=(1<<4)-1; while(!q.empty()) { Node head=q.front(); q.pop(); if(head.x==x2&&head.y==y2)return; for(int a=0;a<4;a++) { for(int b=1;b<=k;b++) { temp.x=head.x+b*ma[a][0]; temp.y=head.y+b*ma[a][1]; if(!check(temp.x,temp.y)||s1[temp.x][temp.y]=='#')break; if(vis[temp.x][temp.y]&(1<<a))break; int flag=0; if(!vis[temp.x][temp.y]) flag=1; vis[temp.x][temp.y]|=(1<<a); if(flag) { dis[temp.x][temp.y]=dis[head.x][head.y]+1; q.push(temp); } } } } return ; } int main() { while(scanf("%d%d%d",&n,&m,&k)!=EOF) { for(int a=1; a<=n; a++) scanf("%s",s1[a]+1); int starx,stary,finax,finay; scanf("%d%d%d%d",&starx,&finax,&stary,&finay); bfs(starx,finax,stary,finay); if(vis[stary][finay])printf("%d\n",dis[stary][finay]); else printf("-1\n"); } return 0; }