SJTUOJ1003路径法解决问题

题目如下:
二哥不仅种苹果和花生,还养了很多细菌。二哥的细菌培养皿成方格形,边长为L。长期培养后,二哥发现了细菌繁殖的规律:最初每个格子里的细菌及其后代都会独立繁殖,每次繁殖都会在其上下左右四个相邻的格子里产生新的细菌,而已经存在的细菌在培养皿充满细菌之前都不会死亡。另外,有一些格子里可能还有抗生素,细菌在有抗生素的格子里无法繁殖。

二哥于是发明了一个游戏:取一个新的培养皿,在某些格子里放入细菌或抗生素,然后观察细菌不断繁殖直至充满整个培养皿的所有没有抗生素的格子。不过二哥已经对这个游戏厌烦了,他现在只想知道经过多少轮繁殖后,细菌会充满整个培养皿(不算有抗生素的格子)。

输入格式
第1行有1个整数,边长L。

第2行至第L+1行,每行有L个整数,取值为0、1或2。0表示格子里最初没有细菌,1表示格子里最初有细菌,2表示格子里最初有抗生素。

输出格式
输出一个整数m,表示经过m轮繁殖后,细菌会充满整个培养皿(不算有抗生素的格子)。

说明
【样例解释】 第一轮繁殖:

2 1 0

1 1 1

0 1 0

第二轮繁殖:

2 1 1

1 1 1

1 1 1

【数据范围】

对于全部数据:1≤L≤1001≤L≤100 ,保证最终能够充满培养皿(不算有抗生素的格子)。

Sample Input
3
2 0 0
0 1 0
0 0 0
Sample Output
2

第一遍做的想法很简单,就是遍历法。但是遍历的效率无疑是极为低下,每次需要遍历l^2个数。
后来这样想的:
每个细菌培养皿每次都会向四周扩展,除非培养基上是抗生素。如果把细菌看成是路径上的蚂蚁,问题就变成了每个细菌爬到空白培养基所需要的时间。在大量重复冗余的情况下我们只需要考虑对于每个空白培养基,距离他距离最近的细菌爬到他这里的时间;将每个空白培养基所需要的时间加以比较,最长的那个时间或者说是培养轮数就是我们要求的。
也就是说,从数据的角度加以阐释的话,对于每个0,我们需要找到离他最近的那个1;而且这个路径要考虑折线,考虑路障(所有的2都可以视为路障)。
而这样一来,本问题下考虑测算路径就成了最大的问题。

bool isFound (int l,int **matrix,int step,int i,int j)
{
    if(i<0||j<0||i>l-1||j>l-1)
        return false;
    if(step==0)
        if(matrix[i][j]==1)
            return true;
        else return false;
    if(matrix[i][j]==2)
        return false;
    return (isFound(l,matrix,step-1,i-1,j)||isFound(l,matrix,step-1,i+1,j)
       ||isFound(l,matrix,step-1,i,j-1)||isFound(l,matrix,step-1,i,j+1));
}
//测算step步之内是否存在一个1

递归的思想。遇见2直接返回一个否;因为后面用的是或语句,所以不影响,甚至感觉很巧妙。
总体代码如下:

//宇宙第一路径法 666
#include<iostream>
using namespace std;
bool isFound (int l,int **matrix,int step,int i,int j)
{
    if(i<0||j<0||i>l-1||j>l-1)
        return false;
    if(step==0)
        if(matrix[i][j]==1)
            return true;
        else return false;
    if(matrix[i][j]==2)
        return false;
    return (isFound(l,matrix,step-1,i-1,j)||isFound(l,matrix,step-1,i+1,j)
       ||isFound(l,matrix,step-1,i,j-1)||isFound(l,matrix,step-1,i,j+1));
}
int main (void)
{
    bool sign=false;
    int max=0;
    int l;
    cin>>l;
    int **matrix=new int*[l];
    for(int i=0;i<l;i++)
        matrix[i]=new int[l];
    for(int i=0;i<l;i++)
        for(int j=0;j<l;j++)
        cin>>matrix[i][j];
    for(int i=0;i<l;i++)
        for(int j=0;j<l;j++)
            if(!matrix[i][j])
            {
                int distance=1;
                for(sign=false;sign==false;distance++)
                    sign=isFound(l,matrix,distance,i,j);
                if((distance-1)>max)
                    max=distance-1;
            }
    cout<<max;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值