欢迎来看一个小新手的博客
前几天第一次代表内蒙古大学参加了在上海大学举办的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;
}
虽然代码写的比较烂,但是整体思路大概就是这个样子。