RQNOJ 35 营救 解题报告
SPFA,纯搜索,如果走到下一个位置的体力可以更少那就用那个更少的,如果一样多,看走的步数,用少的,就这样一个广搜。
代码如下:
#include <math.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define QMAX 25000 struct node{ int x, y; }queue[QMAX]; int head, rear; int map[500][500]; int used[500][500]; void enqueue(int x, int y) { if(used[x][y]){ return; } used[x][y] = 1; queue[rear].x = x; queue[rear].y = y; rear = (rear + 1) % QMAX; } void exqueue(int *x, int *y) { *x = queue[head].x; *y = queue[head].y; used[*x][*y] = 0; head = (head + 1) % QMAX; } int dis[500][500]; int step[500][500]; int ans1 = 0x7FFFFF, ans2; int main(int argc, char **argv) { char c; int i, j; int m, n; int x, y; scanf("%d%d", &n, &m); scanf("%d%d", &x, &y); memset(dis, 0x7F, sizeof(dis)); memset(step, 0x7F, sizeof(step)); dis[x - 1][y - 1] = 0; step[x - 1][y - 1] = 1; enqueue(x - 1, y - 1); scanf("%d%d\n", &x, &y); for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ scanf("%c", &c); map[i][j] = c - '0'; } scanf("\n"); } while(head != rear){ exqueue(&i, &j); #define deal(s, t) do{\ if(s >= 0 && s < n && t >= 0 && t < m){\ if((map[s][t] != 0) && (dis[s][t] >= dis[i][j] + abs(map[i][j] - map[s][t]))){\ if(dis[s][t] > dis[i][j] + abs(map[i][j] - map[s][t])){\ step[s][t] = step[i][j] + 1;\ dis[s][t] = dis[i][j] + abs(map[i][j] - map[s][t]);\ enqueue(s, t);\ }else if(step[s][t] > step[i][j] + 1){\ step[s][t] = step[i][j] + 1;\ enqueue(s, t);\ }\ }\ }\ }while(0) deal(i - 1, j - 1); deal(i - 1, j); deal(i - 1, j + 1); deal(i, j - 1); deal(i, j + 1); deal(i + 1, j - 1); deal(i + 1, j); deal(i + 1, j + 1); } if(dis[x - 1][y - 1] == 0x7F7F7F7F){ printf("0 0\n"); }else{ printf("%d %d\n", step[x - 1][y - 1], dis[x - 1][y - 1]); } return 0; }