链接
题目描述
题目中的
样例输入 #1
5 4 0 0 5
. 1 T 1
. . . 2
. 1 . .
S . . .
1 . . .
样例输出 #1
3 0 0
样例输入 #2
8 6 2 3 3
. S . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
2 . 2 . 2 .
. . 1 . T .
3 . 1 . . 3
样例输出 #2
3 1 3
样例输入 #3
8 6 5 5 2
. S . . . .
. . . . . .
. . . . . .
1 1 3 2 . 1
2 3 2 2 1 3
3 2 4 1 4 3
2 6 1 5 T 2
8 1 6 3 2 10
样例输出 #3
-1
思路
广搜,枚举八个方向以及闪现的四个方向,再加个判断隐身就可以了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int n, c1, c2, d, m, sx, sy, tx, ty, ans1, ans2, ans;
int b[505][505], Ans[505][505][26][26];
int dx[13] = {0, 0, 0, 1, -1, +1, +1, -1, -1};
int dy[13] = {0, 1, -1, 0, 0, -1, +1, +1, -1};
int d2[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1};
struct lL
{
int x, y, c1, c2;
};
char read()
{
char cc = getchar(), num = 0;
while(cc != '.' && cc != 'S' && cc != 'T' && !(cc >= 48 && cc <= 65)) cc = getchar();
if(cc == 'S') return -1;
if(cc == 'T') return -2;
else {
while(cc >= 48 && cc <= 65)
num = num * 10 + cc - 48, cc = getchar();
return num;
}
}//处理读入的数据
void chuli(int x, int y, int r)
{
for(int i = 0; i <= r; ++i)
for(int j = 0; j <= r - i; ++j)
{
if(x + i <= n && y + j <= m) b[x + i][y + j] = max(b[x + i][y + j], 1);
if(x - i >= 1 && y + j <= m) b[x - i][y + j] = max(b[x - i][y + j], 1);
if(x + i <= n && y - j >= 1) b[x + i][y - j] = max(b[x + i][y - j], 1);
if(x - i >= 1 && y - j >= 1) b[x - i][y - j] = max(b[x - i][y - j], 1);
}
b[x][y] = 2;
}//没用差分,直接将所有可以观测到的点标记
bool check(int x, int y, int c1, int c2)
{
if(x < 1 || x > n || y < 1 || y > m || c1 < 0 || c2 < 0) return 0;
if(Ans[x][y][c1][c2] > 0 || b[x][y] == 2) return 0;
return 1;
}
void bfs()
{
queue<lL>Q;
Q.push((lL){sx, sy, c1, c2});
while(Q.size())
{
int x = Q.front().x, y = Q.front().y, j1 = Q.front().c1, j2 = Q.front().c2;
Q.pop();
if (x == 3 && y == 5) {
int aba;
aba = 21;
}
for(int i = 1; i <= 12; ++i)
{
int nx = x + dx[i], ny = y + dy[i], ji1 = 0, ji2 = d2[i];
if(b[nx][ny] == 1) ji1 = 1;//记录消耗次数
if(check(nx, ny, j1 - ji1, j2 - ji2)) {
Q.push((lL){nx, ny, j1 - ji1, j2 - ji2});
Ans[nx][ny][j1 - ji1][j2 - ji2] = Ans[x][y][j1][j2] + 1;
}
}
}
}
void outt()
{
ans1 = ans2 = ans = 1e9;
for(int i = 0; i <= c1; ++i)
for(int j = 0; j <= c2; ++j)
if(Ans[tx][ty][i][j] && (Ans[tx][ty][i][j] < ans || (Ans[tx][ty][i][j] == ans && i + j > ans1 + ans2) || (Ans[tx][ty][i][j] == ans && i + j == ans1 + ans2 && i > ans1))) {
ans = Ans[tx][ty][i][j];
ans1 = i;
ans2 = j;
}
if(ans != 1e9) printf("%d %d %d", ans, c1 - ans1, c2 - ans2);
else printf("-1");
}
int main()
{
scanf("%d%d%d%d%d", &n, &m, &c1, &c2, &d);
dx[9] = d; dx[10] = -d;
dy[11] = d; dy[12] = -d;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
{
int c = read();
if(c == -1) sx = i, sy = j;
if(c == -2) tx = i, ty = j;
if(c > 0) chuli(i, j, c - 1);
}
bfs();
outt();
return 0;
}