题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2653
http://acm.hdu.edu.cn/showproblem.php?pid=2579
题目的意思都很简单,主要写这篇博客的原因是学会了状态标记这个技巧,对于迷宫各种类 的,每个位置可以多次走过 的且对于每个格子的状态较少,可以多加一维来进行状态标记。
2653,对于每个位置,其余数就是一个状态。。比较简单。。一开始,自己想的各种,都是错的。。后来有了这个个技巧,马上就AC了。。这绝对的一个很好的技巧
Code:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 85;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
int n, m, t, p, bx, by;
char map[N][N];
bool vis[N][N][N];//mark for the states...
struct Node{
int x, y;
int ener, step;
Node(){ }
Node(int a, int b, int c, int d){
x = a; y = b;
ener = c; step = d;
}
bool friend operator < (Node X, Node Y){
if(X.step > Y.step) return true;
return false;
}
};
void bfs(){
memset(vis, 0, sizeof(vis));
priority_queue<Node> q;
q.push(Node(bx, by, p, 0));
vis[bx][by][p] = true;
while(!q.empty()){
Node tmp1 = q.top(), tmp2;
if(tmp1.step > t) break;
q.pop();
if(map[tmp1.x][tmp1.y] == 'L'){
if(tmp1.step <= t) printf("Yes, Yifenfei will kill Lemon at %d sec.\n", tmp1.step);
else puts("Poor Yifenfei, he has to wait another ten thousand years.");
return ;
}
// printf("%d %d %d %d\n", tmp1.x, tmp1.y, tmp1.step, tmp1.ener);
for(int i = 0; i < 4; i ++){
tmp2.x = tmp1.x + dx[i]; tmp2.y = tmp1.y + dy[i];
if(tmp2.x < 1 || tmp2.x > n || tmp2.y < 1 || tmp2.y > m || map[tmp2.x][tmp2.y] == '#') continue;
if(tmp1.ener != 0 && !vis[tmp2.x][tmp2.y][tmp1.ener - 1]){ // fly
tmp2.ener = tmp1.ener - 1;
tmp2.step = tmp1.step + 1;
vis[tmp2.x][tmp2.y][tmp2.ener] = true;
q.push(tmp2);
}// walk..
if(map[tmp1.x][tmp1.y] != '@' && map[tmp2.x][tmp2.y] != '@' && !vis[tmp2.x][tmp2.y][tmp1.ener]){
tmp2.ener = tmp1.ener;
tmp2.step = tmp1.step + 2;
vis[tmp2.x][tmp2.y][tmp2.ener] = true;
q.push(tmp2);
}
}
}
puts("Poor Yifenfei, he has to wait another ten thousand years.");
return ;
}
int main(){// you can step on the same gird if you have the different power
int k = 0;
// freopen("11.txt", "r", stdin);
while(~scanf("%d %d %d %d", &n, &m, &t, &p)){
getchar();
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
scanf("%c", &map[i][j]);
if(map[i][j] == 'Y') bx = i, by = j;
}
getchar();
}
printf("Case %d:\n", ++ k);
bfs();
}
return 0;
}
另外一道题,也是很easy的题目,同样,状态很少。。
Code:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 105;
const int M = 15;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
char map[N][N];
bool vis[N][N][M];
int n, m, k, bx, by;
struct Node{
int x, y;
int step;
Node(){ }
Node(int a, int b, int c){
x = a;
y = b;
step = c;
}
bool friend operator < (Node X, Node Y){
if(X.step > Y.step) return true;
return false;
}
};
void bfs(){
memset(vis, 0, sizeof(vis));
priority_queue<Node> q;
q.push(Node(bx, by, 0));
vis[bx][by][0] = true;
while(!q.empty()){
Node tmp1 = q.top(), tmp2;
q.pop();
if(map[tmp1.x][tmp1.y] == 'G'){
printf("%d\n", tmp1.step);
return ;
}
// printf("%d %d %d\n", tmp1.x, tmp1.y, tmp1.step);
for(int i = 0; i < 4; i ++){
tmp2.x = tmp1.x + dx[i]; tmp2.y = tmp1.y + dy[i];
if(tmp2.x < 1 || tmp2.x > n || tmp2.y < 1 || tmp2.y > m) continue;
if(map[tmp2.x][tmp2.y] == '#' && (tmp1.step + 1) % k == 0){
tmp2.step = tmp1.step + 1;
q.push(tmp2);
}
else if(map[tmp2.x][tmp2.y] != '#' && !vis[tmp2.x][tmp2.y][(tmp1.step + 1) % k])
{
tmp2.step = tmp1.step + 1;
vis[tmp2.x][tmp2.y][tmp2.step % k] = true;
q.push(tmp2);
}
}
}
puts("Please give me another chance!");
return ;
}
int main(){
// freopen("1.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T --){
scanf("%d %d %d", &n, &m, &k);
getchar();
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
scanf("%c", &map[i][j]);
if(map[i][j] == 'Y') bx = i, by = j;
}
getchar();
}
bfs();
}
return 0;
}
应该尽快吧这几十道题目A了。。留给我们的时间确实已经不多了。。