Flood-it! poj4007 (IDA*)


题目链接:https://cn.vjudge.net/problem/POJ-4007


题解:

        将与左上角相连且颜色相同的格子设为A类格子;与A类格子相连的格子,即颜色为A类格子下一步可变为的颜色的格子设为B类格子;将A类格子标记为1,表示当前状态颜色已改变的格子,将B类格子标记为2,表示当前状态颜色可改变的格子。

        MHD( )(曼哈顿距离):此题的曼哈顿距离求的是除了A类格子外剩余格子的颜色的数量,也就是最少需要改变颜色的次数。

        dfs( )(搜索过程):先判断当前结果是否与假定最优解相同,若不同则判断当前状态的最优解+当前深度是否大于假定最优解(IDA*优化);然后遍历六种颜色,定义一个局部变量记录当前状态(回溯后即可回溯到此状态),找到一个B类格子后改变当前状态(change_state()函数),继续下一步搜索。

        change_state( )( 改变状态 ) :将与当前A类格子(进入此调用函数前的刚被标记为A类格子的B类格子,不是其他颜色的A类格子)颜色相同的格子标记为1(标记为A类格子),与其相连的标记为2(标记为B类格子);


总结:

        这个题对于自己来说,算是一个经典的题。做的时候不知道该如何回溯,具体搜索的过程思路不太清晰。改变状态时用的也是dfs,自己没有想到。发现自己身上的很大弊端,在做题时没有一个具体明确的思路,很多细节的东西也处理不太好。路还很长,希望自己更加努力吧。

#include<stdio.h>
#include<string.h>
int n;
int c[4][2]= {1,0,0,1,-1,0,0,-1};
int book[10][10];
int Map[10][10];
int min_step;
int flag;
int ans;

int MHD()///曼哈顿距离(求的是当前还剩余的颜色数目);
{
    int i,j,k=0,num[10]= {0};
    for(i=0; i<n; i++)
        for(j=0; j<n; j++)
        {
            if(book[i][j]==1)
                continue;
            num[Map[i][j]]=1;
        }
    for(i=0; i<6; i++)
        if(num[i])
            k++;
    return k;
}

void change_state(int x,int y,int color)///改变当前状态;
{
    for(int i=0; i<4; i++)
    {
        int dx=x+c[i][0];
        int dy=y+c[i][1];
        if(dx<0||dy<0||dx>=n||dy>=n||book[dx][dy]==1)
            continue;
        if(Map[dx][dy]==color)
        {
            book[dx][dy]=1;
            change_state(dx,dy,color);
        }
        else
            book[dx][dy]=2;
    }
}

void dfs(int s)
{
    if(flag)
        return ;
    int mhd=MHD();
    if(s==min_step)
    {
        if(mhd==0)
        {
            flag=1;
            ans=min_step;
        }
        return ;
    }
    if(mhd+s>min_step)///IDA*;
        return ;
    int i,j,k;
    for(i=0; i<6; i++)
    {
        int last_book[10][10];///定义局部变量储存当前状态;
        int cnt=0;
        memcpy(last_book,book,sizeof(book));
        for(j=0; j<n; j++)
            for(k=0; k<n; k++)
            {
                if(Map[j][k]!=i)
                    continue;
                if(book[j][k]==2)///当前格子为2时表示可改变;
                {
                    book[j][k]=1;
                    change_state(j,k,i);
                    cnt++;
                }
            }
        if(!flag&&cnt>0)
            dfs(s+1);
        if(flag)
            return ;
        memcpy(book,last_book,sizeof(last_book));///回溯到上一个状态;
    }
}

int main()
{
    while(~scanf("%d",&n)&&n)
    {
        int i,j;
        for(i=0; i<n; i++)
            for(j=0; j<n; j++)
                scanf("%d",&Map[i][j]);
        memset(book,0,sizeof(book));
        book[0][0]=1;//左上角的格子为A类格子;
        change_state(0,0,Map[0][0]);
        min_step=MHD();///假定最优解;
        flag=0;
        while(!flag)
        {
            dfs(0);
            min_step++;
        }
        printf("%d\n",ans);
    }
}
`iptables pingflood-IN`通常是指在Linux系统中配置iptables规则来阻止ping洪泛攻击进入特定网络设备(如路由器或防火墙)。iptables是一个强大的包过滤工具,用于在Linux内核中控制网络数据包的流向。 ### 简介 iptables通过在内核级别的规则表上设置规则来管理数据包流量,它可以进行链路筛选、源地址限制等多种功能。在网络安全策略中,经常需要使用iptables来防御各种类型的攻击,包括但不限于ping洪泛攻击。 ### 防御ping洪泛攻击的iptables规则示例 为了防御ping洪泛攻击,可以创建一条iptables规则禁止特定IP地址向目标主机发起ping请求。以下是基本的iptables命令行结构: ```bash sudo iptables -A INPUT -p icmp --icmp-type echo-request -s <source_ip> -j DROP ``` 这里的参数说明如下: - `sudo`: 使用管理员权限运行iptables命令。 - `-A INPUT`: 将规则添加到INPUT链,这表示只允许接收的数据包经过此规则检查。 - `-p icmp`: 指定处理ICMP协议的数据包。 - `--icmp-type echo-request`: 这是发送PING请求的ICMP类型标识符(Type 8)。 - `-s <source_ip>`: 只针对来自特定IP地址的包。 - `-j DROP`: 表明将匹配的包丢弃,即拒绝接收来自该IP地址的所有PING请求。 ### 应用场景 1. **部署安全服务器**:在网络环境中,服务器可能会受到频繁的ping洪泛攻击,导致网络拥塞并影响正常服务。通过上述iptables规则,可以有效隔离这样的攻击。 2. **企业内部网络防护**:对于有严格安全需求的企业内部网络,防止从外部对内部服务器发起的恶意Ping尝试也很重要。 ### 注意事项 1. **权衡性能**:虽然iptables能提供强大的安全保护,但也可能导致一定的CPU开销和延迟,特别是在高流量网络环境下。 2. **测试与监控**:在实施新的iptables规则之前,应先在非关键环境中测试其效果,并持续监控网络流量,确保不会误拦截正常的通信。 3. **定期更新规则**:随着网络威胁的不断演变,可能需要调整iptables规则以应对最新的攻击手段。 --- ### 相关问题: 1. 怎么确定是否有正在进行的ping洪泛攻击? 2. iptables的其他常用规则有哪些? 3. 在设置iptables规则时需要注意哪些常见陷阱?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值