题目:题目链接
题目的意思是用虽少的机器人来看守宝藏,这里的机器人只可以看守一个方向的地点,并且无法越过障碍物。给你一幅地图,上面有三种符号*代表宝藏,#代表障碍物。.代表空地。机器人需要放在宝藏点上。至少需要多少机器人才能看守住宝藏;
分析: 我们可以直接枚举宝藏点,从左上角开始,这样一行行的下来,就无需考虑上方和左方的情况,只需要考虑右方和下方的情况。这样如果一个点是宝藏点并且这个点木有被看守,那么从此点开始向左向下搜索,找到能看受到的范围内的最大宝藏数,直接映射掉就OK,再接着往下检索就OK了,上代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
using namespace std;
char mp[200][200];
int x, y;
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m;
int a, b;
scanf("%d%d", &x, &y);
for(int i = 1; i <= x; ++i)
{
for(int j = 1; j <= y; ++j)
{
mp[i][j] = '.';
}
}
scanf("%d", &n);
for(int i =0; i < n; ++i)
{
scanf("%d%d", &a, &b);
mp[a][b] = '*';
}
scanf("%d", &m);
for(int i =0; i< m; ++i)
{
scanf("%d%d", &a, &b);
mp[a][b] = '#';
}
//scanf("\n");
int ans = 0;
for(int i = 1; i <= x; ++i)
{
for(int j = 1; j <= y; ++j)
{
if(mp[i][j] == '*')
{
//cout << i <<' ' <<j << endl;
ans ++;
int cntx = 0;
//cout << "测试i行:"<<endl;
for(int p = j; p<=y; ++p)
{
if(mp[i][p]=='#')
break;
if(mp[i][p]=='*')
cntx++;
}
int cnty = 0;
//cout << "测试J列:"<<endl;
for(int p = i; p <= x; ++p)
{
if(mp[p][j]=='#')
break;
if(mp[p][j] == '*')
cnty++;
}
if(cntx > cnty)
{
// printf("右边比下面多:\n");
for(int p = j; p <= y; ++p)
{
if(mp[i][p]=='#')
break;
if(mp[i][p]=='*')
mp[i][p] = '.';
}
}
else
{
// printf("下面比右边多:\n");
for(int p = i; p <= x; ++p)
{
if(mp[p][j]=='#')
break;
if(mp[p][j]=='*')
mp[p][j] = '.';
}
}
}
}
}
cout << ans <<endl;
}
return 0;
}
努力努力...