zoukankan      html  css  js  c++  java
  • [JZOJ3106]锻炼

    题目大意:
      给你一个$n imes m(n,mleq 50)$的网格图,其中有一个四连通的障碍物。给定起点和终点,每次你可以走到和当前位置八连通的一个方格内,问绕障碍物一圈最短要走几格?

    思路:
      BFS求一下最短路,然后当一个点被访问两次时,把两次的最短路加起来即可。
      然而这样显然是错的,因为并不能保证两次的路径刚好把障碍物包住,因此我们还需知道每条路径是从障碍物哪边绕过来的。
      一种方法是使用扫描线,当两条路径会合时,从障碍物内一点发射一条扫描线,如果和最短路橡胶的次数时奇数,那么肯定是将障碍物包住了。
      这样据说已经能过了,不过还有一种更妙的方法。
      可以在BFS最短路时,同时记录这条最短路与扫描线相交的次数的奇偶性。
      具体方法是,每次最短路往外扩展一格时,判断一下本次扩展是否经过了扫描线。
      最后两条最短路会合时,只需要判断一下两个最短路经过次数加起来是否为奇数,如果是,则说明将障碍物包起来了,更新答案。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 inline char getblock() {
    12     register char ch;
    13     do {
    14         ch=getchar();
    15     } while(ch!='.'&&ch!='X'&&ch!='*');
    16     return ch;
    17 }
    18 typedef std::pair<int,int> Block;
    19 const int N=50;
    20 const int inf=0x7fffffff;
    21 const int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
    22 Block s;
    23 bool f[N][N];
    24 int n,m,dis[N][N];
    25 std::queue<Block> q;
    26 inline bool check(const Block &u) {
    27     return ~u.first&&u.first<n&&~u.second&&u.second<m&&~dis[u.first][u.second];
    28 }
    29 inline bool calc(const Block &u,const Block &v) {
    30     return (u.first==s.first&&u.second>s.second&&v.first<s.first)||(v.first==s.first&&v.second>s.second&&u.first<s.first);
    31 }
    32 int main() {
    33     n=getint(),m=getint();
    34     for(register int i=0;i<n;i++) {
    35         for(register int j=0;j<m;j++) {
    36             const char ch=getblock();
    37             if(ch=='*') q.push((Block){i,j});
    38             if(ch=='X') {
    39                 s=(Block){i,j};
    40                 dis[i][j]=-1;
    41             }
    42             if(ch=='.') dis[i][j]=inf;
    43         }
    44     }
    45     int ans=inf;
    46     while(!q.empty()) {
    47         const Block u=q.front();
    48         q.pop();
    49         for(register int i=0;i<8;i++) {
    50             const Block v=(Block){u.first+dx[i],u.second+dy[i]};
    51             if(!check(v)) continue;
    52             if(dis[v.first][v.second]==inf) {
    53                 q.push(v);
    54                 dis[v.first][v.second]=dis[u.first][u.second]+1;
    55                 f[v.first][v.second]=f[u.first][u.second]^calc(u,v);
    56             } else {
    57                 if(f[u.first][u.second]^calc(u,v)^f[v.first][v.second]) {
    58                     ans=std::min(ans,dis[u.first][u.second]+dis[v.first][v.second]+1);
    59                 }
    60             }
    61         }
    62     }
    63     printf("%d
    ",ans);
    64     return 0;
    65 }
  • 相关阅读:
    关于jquery判断对象是否为空
    php设计模式学习之观察者模式
    php设计模式学习之单例模式
    Nginx+phpfastcgi下flush输出问题
    php设计模式学习之工厂模式
    centos设置ssh免密码登陆
    关于yii2自带验证码功能不显示问题
    html原样输出html代码
    centos7安装iptables
    centos下配置nginx支持php
  • 原文地址:https://www.cnblogs.com/skylee03/p/8242107.html
Copyright © 2011-2022 走看看