zoukankan      html  css  js  c++  java
  • 1448:【例题1】电路维修

    1448:【例题1】电路维修

    样例

    样例输入                                             样例输出

    3 5                                    1
    \/\
    \///
    /\\
    

     

    题解

          我们可以把电路板上的每个格点(横线与竖线的交叉点)看作无向图中的结点。     
          若两个结点x和y是某个小方格的两个对角,则在x与y之间连边。若该方格中的标准件(对角线)与x到y的线段重合,则边权为0;若垂直相交,则边权为1(说明需要旋转1次才能连通)。然后,我们在这个无向图中求出从左上角到右下角的最短距离,就得到了结果。
           
           这是一个边权要么是0,要么是1的无向图。在这样的图上,我们可以通过双端队列广度搜索计算。
           分支边权为1,从队尾入
           分支边权为0,从队首入
     
     保证两段性和单调性
     

    因为每个节点只需要访问一次,所以算法的时间复杂度为O(R×C)

     
     
     
    注释
    1. make_pair的用法

       无需写出型别, 就可以生成一个pair对象 
      例: 
      make_pair(42,‘%’); 
      而不必费力写成: 
      pair<int, char>(42,‘%’)

     
    2.  if((r+c)%2)   那么无解
        画个图理解一下就好了,毕竟你是要走对角线

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<functional>
    #include<cstdlib>
    #include<utility> 
    
    using namespace std;
    
    const int cap=500010;
    int dist[510][510];    //两点间的最短距离
    char map[510][510];    //读图
    pair<int,int> q[cap*2]; //队列
    int r,c,li,ri;
    inline bool valid(int x,int y)  //是否出界 
    {
        return x>=0&&x<=r&&y>=0&&y<=c;
    }
    
    inline void que_add(int x,int y,int v)  
    {
        if(dist[x][y]<0||v<dist[x][y])
        {
            dist[x][y]=v;
            if(li==ri||v>dist[q[li].first][q[li].second])
              q[ri++]=make_pair(x,y);      //make_pair是生成pair类型的数据 注释1
            else  q[--li]=make_pair(x,y);
        }
    }
    
    int main()
    {
        int kase;
        for(scanf("%d",&kase);kase;--kase)
        {
            scanf("%d %d",&r,&c);
            if((r+c)%2)           //注释2
            {
                for(int i=0;i<r;i++)
                  scanf("%s",map[i]);
                  printf("NO SOLUTION
    ");
            }
            else
            {
                for(int i=0;i<r;i++)
                  scanf("%s",map[i]);
                li=ri=cap;
                q[ri++]=make_pair(0,0);
                memset(dist,-1,sizeof(dist)),dist[0][0]=0;  //初始化距离无穷大
               while(li!=ri)  //队列非空
                {
                    int cx=q[li].first,cy=q[li].second;
                    ++li;
                    if(valid(cx-1,cy-1))
                    {
                        if(map[cx-1][cy-1]=='\') 
                          que_add(cx-1,cy-1,dist[cx][cy]);
                        else que_add(cx-1,cy-1,dist[cx][cy]+1);
                    }
                    if(valid(cx-1,cy-1))
                    {
                        if(map[cx-1][cy]=='/') 
                          que_add(cx-1,cy+1,dist[cx][cy]);
                        else que_add(cx-1,cy+1,dist[cx][cy]+1);
                    }
                    if(valid(cx+1,cy-1))
                    {
                        if(map[cx][cy-1]=='/') 
                          que_add(cx+1,cy-1,dist[cx][cy]);
                        else que_add(cx+1,cy-1,dist[cx][cy]+1);
                    }
                    if(valid(cx+1,cy+1))
                    {
                        if(map[cx][cy]=='\') 
                          que_add(cx+1,cy+1,dist[cx][cy]);
                        else que_add(cx+1,cy+1,dist[cx][cy]+1);  
                    }
                }
                printf("%d
    ",dist[r][c]);
            }
        }
        return 0;
    }
  • 相关阅读:
    [JS Compose] 7. Ensure failsafe combination using monoids
    [Functional Programming] Monad
    [Algorithm] Count Negative Integers in Row/Column-Wise Sorted Matrix
    [React] Use the useReducer Hook and Dispatch Actions to Update State (useReducer, useMemo, useEffect)
    [Functional Programming] Pointy Functor Factory
    [Functional Programming] Async IO Functor
    [Functional Programming] Write simple Semigroups type
    [置顶] 阿里IOS面试题之多线程选用NSOperation or GCD
    JAVA实现字符串反转,借助字符数组实现
    菜鸟级SQL Server21天自学通(文档+视频)
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/10992530.html
Copyright © 2011-2022 走看看