【HDOJ】3442 Three Kingdoms

bfs+状态压缩。初始化数组的曼哈顿距离条件写错了,改了一下午。

  1 /* 3442 */
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <queue>
  7 using namespace std;
  8
  9 #define MAXN 55
 10
 11 typedef struct node_t {
 12     int x, y;
 13     int s, v;
 14     node_t() {}
 15     node_t(int xx, int yy, int ss, int vv) {
 16         x = xx; y = yy; s = ss; v = vv;
 17     }
 18     friend bool operator <(const node_t &a, const node_t &b) {
 19         return a.v > b.v;
 20     }
 21 } node_t;
 22
 23 char map[MAXN][MAXN];
 24 char hurt[MAXN][MAXN][5];
 25 bool visit[MAXN][MAXN][33];
 26 int ls[5] = {2, 3, 0, 2, 1};
 27 int bx, by, ex, ey;
 28 int dir[4][2] = {
 29     {-1,0},{1,0},{0,-1},{0,1}
 30 };
 31 int n, m;
 32
 33
 34 int abs(int x) {
 35     return x<0 ? -x:x;
 36 }
 37
 38 bool check(int x, int y) {
 39     return x<0 || x>=n || y<0 || y>=m;
 40 }
 41
 42 bool invalid(char ch) {
 43     return !(ch==‘$‘ || ch==‘!‘ || ch==‘C‘ || ch==‘.‘);
 44 }
 45
 46 int Manh(int x0, int y0, int x1, int y1) {
 47     return abs(x0-x1) + abs(y0-y1);
 48 }
 49
 50
 51 void init() {
 52     int i, j, k, h, l;
 53     int x, y, z;
 54
 55     memset(hurt, 0, sizeof(hurt));
 56     for (i=0; i<n; ++i) {
 57         for (j=0; j<m; ++j) {
 58             if (map[i][j] == ‘$‘) {
 59                 bx = i;
 60                 by = j;
 61             } else if (map[i][j] == ‘!‘) {
 62                 ex = i;
 63                 ey = j;
 64             } else if (map[i][j]==‘#‘ || map[i][j]==‘.‘) {
 65                 continue;
 66             } else if (map[i][j]>=‘A‘ && map[i][j]<=‘E‘){
 67                 z = map[i][j] - ‘A‘;
 68                 h = z + 1;
 69                 l = ls[z];
 70                 for (x=i-l; x<=i+l; ++x) {
 71                     for (y=j-l; y<=j+l; ++y) {
 72                         if (check(x, y) || Manh(x,y,i,j)>l)
 73                             continue;
 74                         hurt[x][y][z] = h;
 75                     }
 76                 }
 77             }
 78         }
 79     }
 80 }
 81
 82 int bfs() {
 83     int i, j, k;
 84     int x=bx, y=by, s=0, v=0;
 85     node_t nd;
 86     priority_queue<node_t> Q;
 87
 88     memset(visit, false, sizeof(visit));
 89     visit[x][y][s] = true;
 90     Q.push(node_t(x, y, s, v));
 91
 92     while (!Q.empty()) {
 93         nd = Q.top();
 94         if (nd.x==ex && nd.y==ey)
 95             return nd.v;
 96         Q.pop();
 97         for (i=0; i<4; ++i) {
 98             x = nd.x + dir[i][0];
 99             y = nd.y + dir[i][1];
100             s = nd.s;
101             v = nd.v;
102             if (check(x, y) || invalid(map[x][y]) || visit[x][y][s])
103                 continue;
104             visit[x][y][s] = true;
105             for (j=0; j<5; ++j) {
106                 k = 1<<j;
107                 if (hurt[x][y][j] && (s&k)==0) {
108                     v += hurt[x][y][j];
109                     s |= k;
110                 }
111             }
112             Q.push(node_t(x, y, s, v));
113         }
114     }
115
116     return -1;
117 }
118
119 int main() {
120     int t, tt;
121     int i, j, k;
122
123     #ifndef ONLINE_JUDGE
124         freopen("data.in", "r", stdin);
125     #endif
126
127     scanf("%d", &t);
128     for (tt=1; tt<=t; ++tt) {
129         scanf("%d %d", &n, &m);
130         for (i=0; i<n; ++i)
131             scanf("%s", map[i]);
132         init();
133         k = bfs();
134         printf("Case %d: %d\n", tt, k);
135     }
136
137     return 0;
138 }
时间: 2024-11-12 22:17:03

【HDOJ】3442 Three Kingdoms的相关文章

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)

【HDOJ】1686 Oulipo

kmp算法. 1 #include <cstdio> 2 #include <cstring> 3 4 char src[10005], des[1000005]; 5 int next[10005], total; 6 7 void kmp(char des[], char src[]){ 8 int ld = strlen(des); 9 int ls = strlen(src); 10 int i, j; 11 12 total = i = j = 0; 13 while (

【HDOJ】2795 Billboard

线段树.注意h范围(小于等于n). 1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 200005 5 #define lson l, mid, rt<<1 6 #define rson mid+1, r, rt<<1|1 7 #define mymax(x, y) (x>y) ? x:y 8 9 int nums[MAXN<<2]; 10 int h, w; 11 12