经典算法之传染病问题

问题描述:一个坐标表格,每个单元表格就代表一个地方有传染病病毒存在。
无病毒的地方用0标记,有病毒的地方用1标记。(为了方便表示边界,我在周围加了个-1的墙壁)
而我们实际常常研究的是估算受感染程度,该程序需要在接收一个坐标为输入后以该点为中心向周围的8个方向进行递归拓展,检查周围区域是否被感染。得到的菌群用2来标记。类似的应用有图像处理上的ps可以用这个算法找出某种颜色值的分布。

然后要考虑到边界问题:遇到边界应当终止递归。另外还要排除已经访问过的点,即遇到的话也退出递归。
对此我用了个结构体node描述每个区域,offset结构体描述方向。
下面是我的代码:

#include <iostream>  
using namespace std;  
struct node  
{  
    int  value;        // 值为0 无毒,-1(边界墙壁), 1有毒   
    bool bCheck;  
    int  findvirus;    // 发现了有病毒,就给标记为1;  
};  
struct offset  
{  
    int x;  
    int y;  
};  

offset  move[9];

// 本来是6的,但是为了加一层的墙壁,就变8了,墙壁上的值为-1,没有检查为0,检查了为1  
node array[8][8]; // 没有病毒为0,有病毒为1

void InitArray()  
{  
    // 先初始化(墙壁-1,没有病毒为0,有为1) 刚开始的话所有都是未被访问的。应为被我memset为0了呗。。。  
    memset(array,0, sizeof(node)*64);  
    for (int i=0;i<8;i++)  
    {  
        array[i][0].value=-1;  
        array[0][i].value=-1;  
        array[7][i].value=-1;  
        array[i][7].value=-1;  
    }  
    array[1][1].value=1;  
    array[2][2].value=1;  
    array[3][3].value=1;  
    array[3][4].value=1;  
    array[3][6].value=1;  
    array[4][4].value=1;  
    array[4][3].value=1;  
    array[4][6].value=1;  
    array[5][1].value=1;  
    array[5][3].value=1;  
    array[5][4].value=1;  
    array[5][6].value=1;  
    array[6][1].value=1;  


    /  
    move[0].x=0;    // 不动 自己的位置  
    move[0].y=0;  
    move[1].x=0;  
    move[1].y=-1;   // N  
    move[2].x=1;    // NE  
    move[2].y=-1;  
    move[3].x=1;    //  E  
         move[3].y=0;  
    move[4].x=1;    //  ES    
         move[4].y=1;  
    move[5].x=0;    // S  
         move[5].y=1;  
    move[6].x=-1;   //WS  
    move[6].y=1;  
    move[7].x=-1;   // W  
         move[7].y=0;  
    move[8].x=-1;   // WN  
    move[8].y=-1;  

}  
void ShowInitValue()  
{  
    for (int i=0;i<8;i++)  
    {  
        for (int j=0;j<8;j++)  
        {  
            if (array[i][j].findvirus==0)  
            {  
                cout<<array[i][j].value<<"\t";  
            }  
            else  
            {  
                cout<<array[i][j].findvirus<<"\t";  
            }     
        }  
        cout<<"\r\n\r\n\r\n"; // 隔几行显示  
    }  
}  

void RecursiveWork(int x,int y)            // 递归     
{  

    // 检查x,y本身是否有病毒。。。并且标记它为已访问。。当然我得首先写出是否停止退出等等的判断。。  
    if (array[x][y].bCheck==true||array[x][y].value==-1||array[x][y].value == 0 ) // 墙壁或者已经检查过了,或者发现没有感染则结束调用  
    {  
        return ;  
    }    
         array[x][y].bCheck=true;  
    if ( array[x][y].value==1 )  
    {  
        array[x][y].findvirus=2;  
    }  


    int nexti,nextj;  
    for (int index=1;index<9;index++)  
    {  

        nexti=x+move[index].x;  
        nextj=y+move[index].y;  
                  RecursiveWork(nexti,nextj);                     // 内部调用递归  
    }  

}  
int main()  
{  
    InitArray();  
    ShowInitValue();  
    int x,y;  
    cout<<"请输入起始点的x坐标的值:";  
    cin>>x;  
    cout<<"请输入起始点的y的坐标值:";  
    cin>>y;  

    RecursiveWork(x,y);                 // 外部调用递归  

    ShowInitValue();  

    return 0;      
}  

允许结果如下:

转自:
http://blog.csdn.net/qxbailv15/article/details/8961836

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值