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;
}

 

posted @ 2017-11-03 12:42  被咬过的馒头  阅读(175)  评论(0编辑  收藏  举报