题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5025
比赛的时候自己也在写这个。。但是,最后没有写出来。。不是自己写不出来。。只是,当时,思路已经很是混乱了。。表示心情很是糟糕。。其他队也已经a了。也没有心情写了。。很显然,自己比赛时的心态有待改观。。特别是正式的比赛中,心情应该比较平静。。。
题目意思:
孙悟空要救唐三藏,每杀一个蛇需要额外+1时间。钥匙必须是按顺序拿的。。
钥匙最多9把,蛇最多5个。。。
之前自己对于相同的对象,自己不知道怎么来区分,表示,又学习了,对于 相同的对象,我们可以标示他们为不同的对象。。。。。。- - 。。这也很符合人们的基本逻辑思想的。。。。
自己刚开始的做法是对钥匙和蛇一起压缩。。。但是,这样是会MLE的。。。
我们可以发现的是,我们必须按顺序来拿钥匙。。这是这个问题的突破点。。钥匙的状态直接减到10。。很的轻松。。。
Code:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;
const int N = 104;
const int dx[] = {0, 0, -1, 1};
const int dy[] = {1, -1, 0, 0};
int n, m, bx, by;
bool vis[N][N][10][(1 << 5) + 1];
char map[N][N];
struct Node
{
int x, y;
int step, key, s;
Node(){}
Node(int a, int b, int sx, int k, int sn){
x = a; y = b;
step = sx; key = k;
s = sn;
}
};
bool operator < (Node a, Node b)
{
if(a.step > b.step) return true;
return false;
}
void bfs()
{
memset(vis, 0, sizeof(vis));
priority_queue<Node> q;
q.push(Node(bx, by, 0, 0, 0));
vis[bx][by][0][0] = true;
while(!q.empty()){
Node tmp1 = q.top(), tmp2;
q.pop();
// printf("%d %d key = %d snake = %d step = %d\n", tmp1.x, tmp1.y, tmp1.key, tmp1.s ,tmp1.step);
if(map[tmp1.x][tmp1.y] == 'T' && tmp1.key == m){
printf("%d\n", tmp1.step);
return ;
}
for(int i = 0; i < 4; i ++){
tmp2.x = tmp1.x + dx[i]; tmp2.y = tmp1.y + dy[i];
if(tmp2.x > n || tmp2.x < 1 || tmp2.y > n || tmp2.y < 1 || map[tmp2.x][tmp2.y] == '#') continue;
// printf("%d %d %c\n", tmp2.x, tmp2.y, map[tmp2.x][tmp2.y]);
if(map[tmp2.x][tmp2.y] >= 'a' && map[tmp2.x][tmp2.y] <= 'e'){
int snakenum = map[tmp2.x][tmp2.y] - 'a';
tmp2.key = tmp1.key;
if(tmp1.s & (1 << snakenum)){
tmp2.step = tmp1.step + 1;
tmp2.s = tmp1.s;
}
else {
tmp2.s = tmp1.s | (1 << snakenum);
tmp2.step = tmp1.step + 2;
}
if(!vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s]){
q.push(tmp2);
vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s] = true;
}
}
else {
if(map[tmp2.x][tmp2.y] > '0' && map[tmp2.x][tmp2.y] <= '9'){
int keynum = map[tmp2.x][tmp2.y] - '0';
if(tmp1.key == keynum - 1){
tmp2.key = tmp1.key + 1;
}
else tmp2.key = tmp1.key;
tmp2.step = tmp1.step + 1;
tmp2.s = tmp1.s;
if(!vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s]){
q.push(tmp2);
vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s] = true;
}
}
else {
tmp2.key = tmp1.key;
tmp2.s = tmp1.s;
tmp2.step = tmp1.step + 1;
if(!vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s]){
q.push(tmp2);
vis[tmp2.x][tmp2.y][tmp2.key][tmp2.s] = true;
}
}
}
}
}
puts("impossible");
}
int main()
{
// freopen("1.txt", "r", stdin);
while(scanf("%d %d", &n, &m) && (n || m)){
getchar();
int snake = 0;
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){
scanf("%c", &map[i][j]);
if(map[i][j] == 'K') bx = i, by = j;
if(map[i][j] == 'S') map[i][j] = 'a' + snake ++;
}
getchar();
}
bfs();
}
return 0;
}
比较DT的问题是。。。自己交G++ AC。。 C++ TLE。。。
很是无语。。。。。三观尽毁。。。