放置机器人

罗伯特是一位着名的工程师 有一天,老板给了他一项任务。该任务的背景如下:

给定一个由方块组成的地图。有三种块:Wall,Grass和Empty。他的老板想在地图上放置尽可能多的机器人。每个机器人都持有一个激光武器,可同时向四个方向(北,东,南,西)射击。机器人不得不一直呆在最初放置的地方,并一直开火。激光束当然可以通过Grass的网格,但无法通过Wall网格。机器人只能放在空块中。当然老板不希望看到一个机器人伤害另一个机器人。换句话说,两个机器人不得放在一条线上(水平或垂直),除非它们之间有墙。

既然你是一个聪明的程序员和罗伯特最好的朋友之一,他就会请你帮他解决这个问题。也就是说,给定地图的描述,计算可以放置在地图中的最大机器人数。

输入

第一行包含一个整数T(<= 11),它是测试用例的数量。

对于每个测试用例,第一行包含两个整数m和n(1 <= m,n <= 50),它们是映射的行和列大小。然后是m行,每行包含n个字符’#’,’*‘或’o’,分别代表Wall,Grass和Empty。

输出

对于每个测试用例,首先输出一行中的案例编号,格式为:“Case:id”,其中id是测试用例编号,从1开始计数。在第二行只输出可以是的最大机器人数放在那张地图上。

样本输入

2
4 4
o ***

oo#o
*** o
4 4
#ooo
o#oo
oo#o
***#

样本输出

案例:1
3
案例:2
5
解析:构图比较麻烦,将行有空地且能互相攻击的放入A数组,将列的放入B数组,其他还好,有些细节要注意

 #include <iostream>
 #include<vector>
 #include<cstring>
 #include <cmath>
 using namespace std;
 vector <int> f[2505];
 char mapa[55][55];
 int n,m,t,x=1,y=1,cs,a[55][55],b[55][55],link[2505],z;
 bool color[2505];
 bool find (int i)
 {
 	for (int j=0;j<f[i].size();j++)
 	{
 		if (color[f[i][j]]==0)
 		{
 			color[f[i][j]]=1;
 			int q=link[f[i][j]];
 			link[f[i][j]]=i;
 			if (q==0||find(q)) return true;
 			link[f[i][j]]=q;
 		}
 	}	
 	return false;
 }
 void jm()
 {
 	bool p=0;
 	for (int i=1;i<=n;i++)
 			for (int j=1;j<=m;j++)
 			{
 				cin>>mapa[i][j];
 				if (j==1&&p==1)
 				{
 					p=0;
 					x++;
 				} 				  
 				if (mapa[i][j]=='o')	 
				 {
				 	a[i][j]=x;
					p=1;
					z=x;
				 }
 			    if (mapa[i][j]=='#'&&p==1) 
				{
					x++;
					p=0;
				} 
 			}
 			p=0;
 		for (int i=1;i<=m;i++)
		     for (int j=1;j<=n;j++)
			 {
			 	if (j==1&&p==1)
			    {
			    	p=0;
			    	y++;
			    }
			 	if (mapa[j][i]=='o')  
				{
				 	b[i][j]=y;
				 	p=1;
				}
			 	if (mapa[j][i]=='#'&&p==1) 
				 {
				 	y++;
				 	p=0;
				 } 
			 }
	return;
 }
 void lb ()
 {
 	for (int i=1;i<=n;i++)
 	  for (int j=1;j<=m;j++)
 	  {
 	  	if (mapa[i][j]=='o')
 	  	{
 	  	//	cout<<a[i][j]<<" "<<b[j][i]<<endl;
 	  		f[a[i][j]].push_back(b[j][i]); 
 	  	}
 	  
 	  }
 }
 int main()
 {
 	cin>>t;
 	for (int i=1;i<=t;i++)
 	{
 		for (int j=1;j<=2504;j++)//一定要循环到这么多,第一次卡了好久
 		{
 		    f[j].clear();
 		}
 		memset(link,0,sizeof(link));
 		memset(a,0,sizeof(a));
 		memset(b,0,sizeof(b));
 		cin>>n>>m;
 		x=1;y=1;
 		jm(); 
		lb();	
		int ans=0; 		
 	    for (int j=1;j<=z;j++)
 	    {
 	    	memset(color,0,sizeof(color));
 	    	ans+=find(j);
 	    }
 	    cout<<"Case :q"<<i<<endl;
 	    cout<<ans<<endl;
 	} 	
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <iostream> #include <vector> using namespace std; int minCount = 1e9; vector<vector<int>> ans; // 存储最优结果 void dfs(int n, int m, vector<vector<int>>& robots, vector<vector<int>>& monitor, int x, int y, int count) { if (y > m) { // 到达行末,进入下一行的递归 dfs(n, m, robots, monitor, x + 1, 1, count); return; } if (x > n) { // 遍历完所有行,更新最优结果 ans = robots;// 更新最少机器人个数 if (count < minCount) { minCount = count; } return; } // 不放置机器人 dfs(n, m, robots, monitor, x, y + 1, count); // 放置机器人 if (monitor[x][y] == 0 && monitor[x - 1][y] == 0 && monitor[x][y - 1] == 0 && monitor[x][y + 1] == 0 && monitor[x + 1][y] == 0) { robots[x][y] = 1; monitor[x][y] = 1; monitor[x - 1][y] = 1; monitor[x][y - 1] = 1; monitor[x][y + 1] = 1; monitor[x + 1][y] = 1; dfs(n, m, robots, monitor, x, y + 1, count + 1); monitor[x][y] = 0; monitor[x - 1][y] = 0; monitor[x][y - 1] = 0; monitor[x][y + 1] = 0; monitor[x + 1][y] = 0; robots[x][y] = 0; } } int main() { int n, m; cin >> n >> m; vector<vector<int>> robots(n + 2, vector<int>(m + 2, 0)); // 机器人位置 vector<vector<int>> monitor(n + 2, vector<int>(m + 2, 0)); // 监视情况 ans = robots; // 初始化最优结果 dfs(n, m, robots, monitor, 1, 1, 0); // 输出最优结果 cout << "最优安排的机器人数是:"<< minCount << endl; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cout << ans[i][j] << " "; } cout << endl; } return 0; }为什么这串代码统计的最少安排机器人个数与机器人布局不一致,能够将代码修改正确
最新发布
05-30

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值