火力网加强版(difficult)

该问题描述了一个正方形城市的布局,其中包含空地和墙,目标是在城市中放置碉堡,使得没有两个碉堡可以互相射击。碉堡必须位于空地上,且不能在同一行或同一列,除非中间有墙。任务是编程求解在给定地图中,最多可以放置多少个碉堡。示例输入和输出展示了如何读取地图并计算最大合法碉堡数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

火力网加强版(difficult)

Time Limit:1000MS  Memory Limit:65536K
Total Submit:32 Accepted:12

Description

  假定我们有一个正方形的城市,拥有笔直的街道。城市由n行n列正方形的地块组成,每一块表示为一个街道或一堵墙。
  碉堡就是一个小的城堡,有四个用于射击的口子。这四个口子分别朝着东、南、西、北方向。每一个口子都有一个用于射击的机关枪。
  我们假定子弹力量很大,足以射到任何距离,并且破坏线路上的碉堡。另一方面,一堵墙非常牢固可以挡住子弹。
  我们的目标就是在城市上放置一些碉堡,使得没有两个碉堡可以互相破坏。碉堡的合法配置就是没有两个碉堡在同一行或同一列上,除非它们之间至少有一堵墙隔在中间。在题目中我们考虑小的正方形城市(最多4×4)包含墙,使得子弹不能穿越。
  下面的图示表示同一个区域,第一个图为空图,第二个和第三个图表示合法的配置,第四个图和第五个图表示违法的配置。对这个区域而言,合法配置的最大的碉堡的数量为5,第二个图显示了一种配置的方法,但还有另外的方法。

  你的任务就是编程,对于给出的地图,计算碉堡的最大数量,可以合法配置在城市中。
  

Input

  输入的第一行为n表示一个地图的大小,n最多为10,下面n行表示地图的每一列,一个‘.’表示空地,‘X’表示墙。
  

Output

输出一个最大的碉堡数量,使得在城市中可以合法配置。

Sample Input

4
.X..
....
XX..
....

Sample Output

5



 
 
  • #include<iostream>
    using namespace std;
    bool used[100];int a[100][100],p[100],re[100],b[100][100],c[100][100];
    int t,tot;
    bool find(int x)
     {
     	int j;
     	for(j=1;j<=t;j++)
     	 {
     	 	if(a[x][j]&&used[j]!=1)
     	 	 {
     	 	 	used[j]=1;
     	 	 	if(p[j]==false||find(p[j]))
     	 	 	 {
     	 	 	 	p[j]=x;
     	 	 	 	return true;
     	 	 	 }
     	 	 }
     	 }
      return false;	 
     }
    int main()
     {
     	int n,l=0;char x,y;
     	cin>>n;
     	for(int i=1;i<=n;i++)
     	 for(int j=1;j<=n;j++)
     	 {
     	  cin>>x;
     	  if(x=='.')b[i][j]=0;
    	   else b[i][j]=-1; 
         }
     	for(int i=1;i<=n;i++)
     	 {
     	 int j=1;	
     	  if(b[i][j]!=-1)l++;	
     	  while(j<=n)
     	   {
     	  	if(b[i][j]==0)b[i][j]=l;
     	  	 else
     	  	  {
     	  	  	while(b[i][j]==-1)j++;
     	  	  	l++;
     	  	  	b[i][j]=l;
     	  	  }
     	  	 j++; 
     	   }
         }
         int k=0;
         for(int i=1;i<=n;i++)
     	 {
     	 int j=1;	
     	  if(b[j][i]!=-1)t++;	
     	  while(j<=n)
     	   {
     	  	if(b[j][i]>0)c[j][i]=t;
     	  	 else
     	  	  {
     	  	  	while(b[j][i]==-1)
    				 {
                      c[j][i]=-1;
                      j++;
                     }
     	  	  	t++;
     	  	  	c[j][i]=t;
     	  	  }
     	  	 j++; 
     	   }
         }
    	 for(int i=1;i<=n;i++)
    	  for(int j=1;j<=n;j++)
    	   if(b[i][j]!=-1&&c[i][j]!=-1)a[b[i][j]][c[i][j]]=true;	 
     int ans=0;	 
    for(int i=1;i<=l;i++)
     {
     	for(int j=1;j<=t;j++)used[j]=false;
     	if(find(i))ans++;
     }	 
     cout<<ans;
    	 
     } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值