zoukankan      html  css  js  c++  java
  • USACO 2.4 Overfencing 【种子染色法+递推】

    题在这
    https://www.luogu.org/problem/show?pid=1519
     
    分析:
    这个题有以下几个难点:
    1、输入时回车的处理
    2、奇数行与列不能计数的问题
    3、在众多最小值中取最大的逻辑问题
    4、单终点最短路径,多次搜索方案优化问题
     
    也同时有以下几个窍门:
    1、把字符转化成ASCII码存于二维数组中
    2、每次移动时跳一格,但要判断中间是否有墙
    3、先独立地求出每一点的最短路径,再遍历每一个点,找最大的“糟糕点”
    4、用种子染色法,从两个终点开始搜索,遍历全图,每次根据已知点+1的值更新未知点(松弛的方向(从小到大)决定了它不可能搜索出环来),再递归未知点。
     
    下面是参考代码:
     
    /*
    ID: linda_f1
    PROG: maze1
    LANG: C++
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n,m;//M排,N列 
    int map[300][300]={0};//0 represents free to pass while 1 represents not
    int maxx=0;
    int derx[5]={0,2,0,-2,0};
    int dery[5]={0,0,2,0,-2};
    int dfs(int x,int y)
    {
     int xx,yy,ax,ay;  
     for(int i=1;i<=4;i++)
     {
      int flag=0;
      xx=x+derx[i];
      yy=y+dery[i];
      ax=x+derx[i]/2;
      ay=y+dery[i]/2;
      if(map[ax][ay]!=-1&&map[xx][yy]!=-1&&map[xx][yy]>map[x][y]+1&&xx>=1&&xx<=m&&yy>=1&&yy<=n)
      {
       map[xx][yy]=map[x][y]+1;//松弛操作
       dfs(xx,yy); 
      }
     }
    }
    int main()
    {
     freopen("maze1.in","r",stdin);
     freopen("maze1.out","w",stdout);
     memset(map,31,sizeof(map));
     cin>>n>>m;
     m=m*2+1;
     n=n*2+1;
    // int s[6],sum=0; 
     for(int i=1;i<=m;i++)
     {
      char c;
       scanf("%c",&c);//在每行的开始会有一个回车,处理掉它 
      for(int j=1;j<=n;j++)
      {
       scanf("%c",&c);
       if(c=='+'||c=='-'||c=='|')
        map[i][j]=-1;
    //   if(c==' '&&(i==m||i==1||j==n||j==1))
    //   {
    //    s[++sum]=i;
    //    s[++sum]=j; 
    //   }
      }
     }
     //下面是寻找那两个出口,并开始搜索 
     for(int i=1;i<=m;i++)
     {
      if(map[i][1]!=-1) 
      {
       map[i][2]=1;
       dfs(i,2); 
      }
      if(map[i][n]!=-1) 
      {
       map[i][n-1]=1; 
       dfs(i,n-1);
      }
     }
     for(int i=1;i<=n;i++)
     {
      if(map[1][i]!=-1) 
      {
       map[2][i]=1;
       dfs(2,i); 
      }
      if(map[m][i]!=-1) 
      {
       map[m-1][i]=1; 
       dfs(m-1,i);
      }
     }
     for(int i=1;i<=m;i++)
      for(int j=1;j<=n;j++)
      {
       if(map[i][j]>maxx&&map[i][j]<10000)
        maxx=map[i][j];
      }
     cout<<maxx<<endl;
     return 0;
    }
    View Code
  • 相关阅读:
    [转] 股票基础知识
    [原] combobox如何让用户不能输入只能从下拉列表里面选择
    【原】2个面试问题(与同事李将的交流)
    [转] 纯代码取得本机IP地址
    [转] 关于硬盘修复以及低级格式化的一些文章
    [转] 130道C#面试题
    初学Sockets编程(四) 发送和接收数据
    利用Beyond Compare比较文件
    第三日:SimuLink之后是Stateflow
    简单的RPC编程实践——HelloWorld的实现
  • 原文地址:https://www.cnblogs.com/linda-fcj/p/7206207.html
Copyright © 2011-2022 走看看