JOJ 1017(深度优先搜索)

【原题链接】

http://[2001:da8:b000:6221:213:72ff:fe8f:5269]/joj/showproblem.php?pid=1017 (为ipv6地址)

【题目大意】

假设我们有一个有直线街道的方形城市。城市的地图是由N列和N行构成的方形平面,每条表示一条街道或一段墙。
   一个碉堡有四个开口用于射击。这四个开口分别面向北、东、南和西。每个开口都有一个挺机枪。假设子弹的威力很大,可以穿越任何距离而且可以破坏掉线上的碉堡。另一方面墙是非常结实的,可以
挡住子弹。
   目标是在城市中尽可能多的放置碉堡而互不摧毁。碉堡的布局规定是在地图的水平线或垂直列上没有两个碉堡,除非他们中间有墙隔开。在这个问题上我们会考虑有墙的方形小城市(最多4*4)

   你的任务是写一个程序,给出地图的描述,计算出城市中合规定地放置的最大碉堡数目。输入包括一张或多张地图描述,跟着一行以0结束输入。每张地图描述开始以N作为一行,N是城市的大小。N最多是4。接下来的N行每行描述地图中的一行,以一个‘.’象征一个空地,以大写字母‘X’象征一堵墙。在输入过程中没空格。
   每组测试输出一行一个数,即城市中按规定放置的最大碉堡数。

【解题思路】

         深度优先搜索,枚举所有情况,找到最优解,详见代码。

【备注】

         此题为深搜的简单题,若对递归和深搜原理理解不深acmer可研究下此题,注意递归的出口,防止递归进入死循环造成栈溢出。

【源程序】

[code]

#include <iostream>

using namespace std;

 

char map[5][5];

int size,ans;

 

bool canPut(int x, int y)

{//此函数检验该处是否可放

         int i;

         if(map[x][y]=='X') return 0;

         if(map[x][y]=='#') return 0;

         for(i=x;i>=0;i--)

         {

                   if(map[i][y]=='X') break;

                   if(map[i][y]=='#') return 0;

         }

         for(i=x+1;i<size ;i++)

         {

                   if(map[i][y]=='X') break;

                   if(map[i][y]=='#') return 0;

         }

         for(i=y;i>=0;i--)

         {

                   if(map[x][i]=='X') break;

                   if(map[x][i]=='#') return 0;

         }

         for(i=y;i<size;i++)

         {

                   if(map[x][i]=='X') break;

                   if(map[x][i]=='#') return 0;

         }

         return 1;

}

 

bool allPut()

{//此函数检验此图是否有处可放

         int i,j;

         for(i=0;i<size;i++)

         {

                   for(j=0;j<size;j++) if(canPut(i,j)) break;

                   if(j<size) return 0;

         }

         return 1;

}

 

void dfs(int num)//num表示已放的碉堡数

{

         int i,j;

         if(allPut()) { ans=ans>num?ans:num; return; }

         //如果已经无地可放,记录此时放入的碉堡数并更新结果,返回上一层

         for(i=0;i<size;i++) for(j=0;j<size;j++)

         {

                   if(!canPut(i,j)) continue;//如果此处不可放 看下处

                   map[i][j]='#';//此处放碉堡

                   dfs(num+1);//递归到下层检验是否可再放

                   map[i][j]='.';//下层不可再放,将此处碉堡清空,看另一个分支

         }

}

 

int main()

{

         int i,j;

         while(cin>>size,size)//图大小,遇0结束

         {

                   for(i=0;i<size;i++) for(j=0;j<size;j++) cin>>map[i][j];

                   //输入图

                   ans=0;

                   dfs(0);//深度优先搜索

                   cout<<ans<<endl;//输出结果

         }

         return 0;

}

[/code]

posted on   liugoodness  阅读(442)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2010年3月 >
28 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 1 2 3
4 5 6 7 8 9 10

统计

点击右上角即可分享
微信分享提示