浙江大学ZOJ 1002题 详解

来源:互联网 发布:致远软件合肥 编辑:程序博客网 时间:2024/06/05 00:14

欢迎来看一个小新手的博客


  • 前几天第一次代表内蒙古大学参加了在上海大学举办的ec-final 被狠虐了一顿之后发现了自己不足,和真正的一流大学相比天差地别,于是回来打算尽自己努力练一下自己的算法,起码要每天最少刷一道题吧毕竟已经大二,希望尽力向深黑幻想那样的队伍靠齐吧(虽然真的差的太多了)。于是选择了浙江大学的OJ作为平台,怎么说呢,加油吧。

    话不多说,在自己英语水平极其有限的情况下强行翻译了1002这道题,题目的大概意思是说先要输入一个int类型的数代表了地图的大小(长等于宽),
    然后输入一个地图,类似于

    .X..
    ….
    XX..
    ….

    这样的地图,现在你要在地图里面放置炮楼,.的地方都代表是空地,X的地方都代表是墙,炮楼会向炮楼的一横排和一竖排发射炮弹,但是墙会将炮弹阻拦下来(也就是炮弹不会打到墙的另外一面),为了防止炮楼互相攻击,问你这一整个地图里面能放置最多多少个炮楼。(有点类似于变种八皇后吧)。我能想到的也就是暴力一点的解法深度优先搜索。然后就是上代码;

#include<iostream>using namespace std;int n;char map[100][100];int max_num=0;//用来记录每一回查找到的最大值int max_sum = 0;//用来比较每次查找的最大值的其中的最大值int sum=0;//用来记录当前查找到的已经放置的炮楼的数量int flag=0;//当作标记,用来判断当前这个点有没有放置炮楼//递归函数int blockhouse (){    //遍历的地图查找能放置炮楼的点    for(int x=0;x<n;x++)    {        for(int y=0;y<n;y++)        {            max_num=0;            flag=0;//标记初始化            if(map[x][y]=='.')            {                //如果当前点能够放置炮楼                sum++;                flag=1;                char map_copy[100][100];//记录没放炮楼前的地图                for(int i=0;i<n;i++)                {                    for(int j=0;j<n;j++)                    {                        map_copy[i][j]=map[i][j];                    }                }                //放置炮楼,并且将炮楼四个方向的空地全都打上标记,表示这些点不能够放置炮楼                //左面                map[x][y]='1';                for(int i=y-1;i>=0;i--)                {                    if(map[x][i]=='X')                    {                        break;                    }                    map[x][i]='1';                }                //判断右面                for(int i=y+1;i<n;i++)                {                    if(map[x][i]=='X')                    {                        break;                    }                    map[x][i]='1';                }                //判断上面                for(int i=x-1;i>=0;i--)                {                    if(map[i][y]=='X')                    {                        break;                    }                    map[i][y]='1';                }                //判断下面                for(int i=x+1;i<n;i++)                {                    if(map[i][y]=='X')                    {                        break;                    }                    map[i][y]='1';                }                //基于现在的情况继续查找下一个能够放置炮楼的分支                sum = blockhouse()-1;                //将整个地图复原至上层分支,方便此层分支的另外一种情况分析                for(int i=0;i<n;i++)                {                    for(int j=0;j<n;j++)                    {                        map[i][j]=map_copy[i][j];                    }                }            }            //sum 与flag进行复原至上层分支的情况            if(flag==1)            {                    sum--;                    flag=0;            }            //最大数量判断            if(max_sum<max_num)            {                    max_sum = max_num;                    max_num=0;            }            //递归出口,即为查遍整个地图,分支退出前检查最大值问题            if(x==n-1&&y==n-1)            {                if(sum>max_num)                {                    max_num = sum;                    //cout<<max_num<<endl;                }                return sum;            }        }    }}int main(){    while(cin>>n)    {        if(n==0)        {            break;        }        for(int i=0;i<n;i++)            {            for(int j=0;j<n;j++)            {                cin>>map[i][j];            }        }        blockhouse();        cout<<max_sum<<endl;        max_sum=0;        max_num=0;    }

虽然代码写的比较烂,但是整体思路大概就是这个样子。

1 0