火力网的c语言代码,递归调用

假设我们有一个直街道广场的城市。一个城市的地图用n行n列的方形板,每一个代表一个街道或一块墙。

一个碉堡就是一个小城堡,有四个开口用以射击。四开口面朝北,东,南,西,分别。会有一个机枪射击通过每个开口。

在这里,我们假定子弹是如此强大,它可以运行在任何距离和毁灭的道路上一个碉堡。另一方面,墙是如此强烈地建成,可以阻止子弹。

其目标是把城市中的许多碉堡使没有两个可以摧毁对方。一个配置的碉堡是法律规定,没有两个碉堡是在地图上的同一行或列除非有至少一个壁分离。在这个问题中,我们会考虑小城市广场(最多4×4)包含墙壁透过子弹不能贯穿。
示例
下面的图像显示五张相同的牌。第一张照片是空板,第二和第三的照片显示法律的配置,以及第四和第五的图片显示非法配置。这个委员会,在法律结构的碉堡数目最多为5;第二张图片展示了一种方式,但也有一些其他的方法。

你的任务是写一个程序,设计一个地图,计算碉堡可以放置在城市中的法律配置的最大数量。

#include<malloc.h>
#include<string.h>
#include<stdlib.h>
#include <stdio.h>
void search(int x,int y,int sum);
int bol[4][4];//表示障碍  和  是否有碉堡
int n;
int max=0;//最大数量
int ke(int x,int y);//可以放置碉堡
main()
{
  int i,j;
  char s;
  char ss[4][4];
  while(scanf("%d",&n)!=EOF&&n!=0)
  {
  	max=0;
  	 //printf("\n");
  for(i=0;i<=n-1;i++)
  {
  	getchar(); 
  	for(j=0;j<=n-1;j++)
  	{
  		 	scanf("%c",&ss[i][j]);
  		 	if(ss[i][j]=='X')
  		 	{
  		 		bol[i][j]=-1;
			}
			else
			{
			   	bol[i][j]=0;
		    }
	}
   }
  /* printf("\n");
   for(i=0;i<=n-1;i++)
   {
	   	for(j=0;j<=n-1;j++)
	   	{
	   		printf("%c",ss[i][j]);
		}
		printf("\n");
   }*/
   
    /*for(i=0;i<=n-1;i++)
   {
	   	for(j=0;j<=n-1;j++)
	   	{
	   		printf("%2d",bol[i][j]);
		}
		printf("\n");
   }*/
   //printf("\n");
    search(0,0,0);
    printf("%d\n",max);
  }
 
}
void search(int x,int y,int sum)
{
	int i,j;
	int p,q;
	i=x;
	j=y;
	if(i==n&&j==0) 
    {
    	if(sum>max)
    	{
    		max=sum;
		}
    /*	printf("%d\n",sum);
    	printf("\n");
    	for(p=0;p<=n-1;p++)
    	{
    		for(q=0;q<=n-1;q++)
    		{
    			printf("%2d",bol[p][q]);
			}
			printf("\n");
		}*/
	}
	else
	{
		if(ke(i,j)&&bol[i][j]!=-1)
	    {
	    	if(j!=n-1)
	    	{
		    	bol[i][j]=1;//在此地放置
		    //	printf("测试%d %d\n",i,j);
				search(i,1+j,sum+1);
				bol[i][j]=0;//不在此地放置并重置
				search(i,j+1,sum);
			}
			else
			{
			    bol[i][j]=1;
			//   printf("测试%d %d\n",i,j);
				search(i+1,0,sum+1);
				bol[i][j]=0;
				search(i+1,0,sum);
			}
		}
		else
		{
			if(j!=n-1)
	    	{
	    		search(i,j+1,sum);
			}
			else
			{
				search(i+1,0,sum);
			}
		}
	}
   
}
int ke(int x,int y)
{
	int i,j;
	for(i=y+1;i<=n-1&&bol[x][i]!=-1;i++)//右侧敌人 
	{
		if(bol[x][i]==1)
		{
			return 0;
		}
	}
	for(i=y-1;i>=0&&bol[x][i]!=-1;i--)//左侧敌人 
	{
		if(bol[x][i]==1)
		{
			return 0;
		}
	}
	for(j=x+1;j<=n-1&&bol[j][y]!=-1;j++)//下侧敌人 
	{
		if(bol[j][y]==1)
		{
			return 0;
		}
	}
	for(j=x-1;j>=0&&bol[j][y]!=-1;j--)//上侧敌人
	{
		if(bol[j][y]==1)
		{
			return 0;
		}
	}
	return 1;
}

注释掉的是调试数据的输出。
可以把放置情况输出。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值