zoukankan      html  css  js  c++  java
  • HDU1175

    PS:这一题也是写了二十多遍了,去年这个时候写的,也是写了几天。过几天等考试结束了,集训的时候重新把几种方法再写一下!

    题意:中文题,自行理解。

    思路:

    1. 三维+优先队列写的,跑的时间是最短的,780ms。
    2. dfs+剪枝+判断方向是否改变。跑了辣么长时间6895ms。

    PS:flag标记判断方向就行了。

    三维+优先队列写的,跑的时间是最短的,780ms。

    
    //三维+优先队列
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    int aaa[1100][1100];
    int book[1100][1100][4];
    int aa,bb,cc,dd;
    int flag;
    int n,m;
    int dir[4][2]= {{1,0},{0,-1},{0,1},{-1,0}};
    struct node
    {
        int x;
        int y;
        int step;
        int to;
        // int qqq;
        bool operator < (const node &a)const
        {
            return a.step<step;
        }
    } p,q;
    void bfs(int a,int b,int c,int d)
    {
        book[a][b][0]=1;
        priority_queue<node>Q;
        // queue<node>Q;
    
        p.x=a;
        p.y=b;
        p.step=0;
        p.to=-1;
        Q.push(p);
    
        while(!Q.empty())
        {
            //      q=Q.front();
            q=Q.top();
            Q.pop();
            for(int i=0; i<4; i++)
            {
                p=q;
                p.x+=dir[i][0];
                p.y+=dir[i][1];
                if(p.x>0&&p.x<=n&&p.y>0&&p.y<=m&&(aaa[p.x][p.y]==0||(p.x==cc&&p.y==dd))&&book[p.x][p.y][i]==0)
                    //  if(p.x>0&&p.x<=n&&p.y>0&&p.y<=m&&book[p.x][p.y]==0&&(aaa[p.x][p.y]==0||(p.x==cc&&p.y==dd)))
                {
                    book[p.x][p.y][i]=1;
                    if(p.to!=i)
                    {
                        if(p.step<=2)
                        {
                            p.step=q.step+1;
                            p.to=i;
                        }
                        else
                            continue;
    
                    }
                    else
                    {
                        if(p.step<=3)
                        {
                            p.step=q.step;
                            p.to=i;
                        }
                    }
                    if(p.x==cc&&p.y==dd&&p.step<=3)
                    {
                        flag=1;
                        return;
                    }
                    Q.push(p);
                    //    Q.push(p);
                }
            }
        }
        return ;
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&m)&&(n+m))
        {
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=m; j++)
                {
                    scanf("%d",&aaa[i][j]);
                }
            }
            int ss;
            scanf("%d",&ss);
            while(ss--)
            {
                memset(book,0,sizeof(book));
                flag=0;
                scanf("%d %d %d %d",&aa,&bb,&cc,&dd);
                if((aaa[aa][bb]!=aaa[cc][dd])||aaa[aa][bb]==0||aaa[cc][dd]==0)
                {
                    printf("NO
    ");
                    continue;
                }
                bfs(aa,bb,cc,dd);
                if(flag==0)
                    printf("NO
    ");
                else
                    printf("YES
    ");
            }
        }
        return 0;
    }
    

    dfs+剪枝+判断方向是否改变:

    #include<stdio.h>
    #include<string.h>
    #define inf 0x3f3f3f3f
    
    int a[1100][1100];
    int book[1100][1100];
    int flag,step,k;
    int n,m;
    int aa,bb,cc,dd;
    int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
    void dfs(int x1,int y1,int to,int step)
    {
        book[x1][y1]=1;
        //  if(k)return ;
        if(k||step>3)
            return ;//这里注意剪枝,否则step如果>3但是不满足下一个if语句的话,会进入下一个for循环,每次循环4次,数据大了会超时
        if(x1==cc&&y1==dd)
        {
            if(step<=3)//因为for循环里面进去的step如果是=3且方向改变的话,step会变成4不满足条件
            {
                k=1;
                return;
            }
        }
    
        int face;//判断转弯次数
        for(int i=0; i<4; i++)
        {
            int tx=x1+dir[i][0];
            int ty=y1+dir[i][1];
            if(tx>0&&tx<=n&&ty>0&&ty<=m&&book[tx][ty]==0&&step<=3&&(a[tx][ty]==0||(tx==cc&&ty==dd)))
            {
                //
                face=step;//****
                //控制每一次对于同一个点的四个方向搜的时候,原步数不变,否则每一步都在同一个点的上一步++了
                if(to!=i)//第一次方向肯定改变,因为需要保证步数++,所以后来满足条件的最大step是3
                {
                    // to=i;//***
                    face++;
                }
                else
                {
                    to=to;
                    step=step;//方向想等的时候转弯次数不变
                }
                book[tx][ty]=1;
                dfs(tx,ty,i,face);//递归不是to,是上次走的那个方向也就是i
                //第一次搜的时候第三个位置是to,因为要保证第一个step++
                book[tx][ty]=0;//取标
            }
        }
        return;
    }
    
    int main()
    {
        while(~scanf("%d %d",&n,&m)&&(n+m))
        {
    
            memset(a,0,sizeof(a));
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=m; j++)
                    scanf("%d",&a[i][j]);
            }
            int ss;
            scanf("%d",&ss);
            for(int i=0; i<ss; i++)
            {
                memset(book,0,sizeof(book));
                scanf("%d %d %d %d",&aa,&bb,&cc,&dd);
                if((a[aa][bb]!=a[cc][dd])||a[aa][bb]==0||a[cc][dd]==0)
                {
                    printf("NO
    ");
                    continue;
                }
           //     book[aa][bb]=1;
                //-1判断方向是否改变
                k=0;
                dfs(aa,bb,-1,0);//只能去传入方向是否改变和转弯次数,不能传入坐标(无法记录方向是否改变)
                //只有第一次传入-1,之后传入的都是记录上一次的方向i
                if(k==1)
                    printf("YES
    ");
                if(k==0)
                    printf("NO
    ");
            }
        }
        return 0;
    }
    //4 4
    //1 2 3 4
    //0 0 0 0
    //4 3 1 0
    //0 0 1 0
    //1
    //1 1 4 3
    
  • 相关阅读:
    如何确保消息不丢失?
    消息基于什么传输?
    如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消费了消息?
    消息怎么路由?
    消息如何分发?
    mq 的缺点?
    RabbitMQ 的集群?
    使用 RabbitMQ 有什么好处?
    如何避免消息重复投递或重复消费?
    什么是 rabbitmq?
  • 原文地址:https://www.cnblogs.com/OFSHK/p/13179590.html
Copyright © 2011-2022 走看看