# include # include # include # include # include # include # include # include # include # include using namespace std; const int MAX_N = 200 + 10; const int MAX_M = 100000 + 10; const int MAX_K = 200 + 10; const int MAX_H = 100 + 10; const int MAX_L = 10000 + 10; const double TL = 3.0; /// 5.0 const int U = 200000 + 0; const int D = 200000 + 1; const int L = 200000 + 2; const int R = 200000 + 3; const int P = 200000 + 4; const int buycakes = 5; struct party { int x; int y; int start; int len; }; struct bakery { int x; int y; }; struct sol { int x; int y; int cakes; long long tm; long long score; vector moves; sol () {} sol (int _x, int _y, int _cakes, long long _tm, long long _score, vector _moves) { x = _x, y = _y, cakes = _cakes, tm = _tm, score = _score, moves = _moves; } void print () { int i; ///fprintf (stderr, "score = %lld\n", score); ///fprintf (stderr, "time = %d\n", tm); for (i = 0; i < (int) moves.size (); i ++) { if (moves[i] == U) printf ("U"); if (moves[i] == D) printf ("D"); if (moves[i] == L) printf ("L"); if (moves[i] == R) printf ("R"); if (moves[i] == P) printf ("+"); if (moves[i] <= 100000) printf ("%d", moves[i]); } } }; int n, m, k; int h[MAX_N][MAX_N]; int cb[MAX_N][MAX_N]; int bdist[MAX_N][MAX_N]; int bdir[MAX_N][MAX_N]; int stx, sty; party p[MAX_M]; bakery b[MAX_K]; sol ans, crr; int pos; int aa[4] = {-1, 1, 0, 0}; int bb[4] = {0, 0, -1, 1}; int cc[4] = {D, U, R, L}; vector tmp; inline int mabs (int ppp) { return (ppp < 0) ? -ppp : ppp; } inline bool bomb () { return (double (clock ()) > double (TL * CLOCKS_PER_SEC)); } inline bool ok () { return (!bomb () && crr.tm < 5000000000LL); } bool cmp (party aaa, party bbb) { return aaa.start + aaa.len < bbb.start + bbb.len; } void read () { int i, j; scanf ("%d%d%d", &n, &m, &k); for (i = 1; i <= n; i ++) for (j = 1; j <= n; j ++) scanf ("%d", &h[i][j]); scanf ("%d%d", &stx, &sty); for (i = 0; i < m; i ++) scanf ("%d%d%d%d", &p[i].x, &p[i].y, &p[i].start, &p[i].len); for (i = 1; i <= n; i ++) for (j = 1; j <= n; j ++) cb[i][j] = -1; for (i = 0; i < k; i ++) { scanf ("%d%d", &b[i].x, &b[i].y); cb[b[i].x][b[i].y] = i; } } void init () { priority_queue >> pq; sort (p, p + m, cmp); ans.score = -1; int i, j, cdist, nx, ny, nd, cx, cy; pair > t; pair cpos; for (i = 1; i <= n; i ++) for (j = 1; j <= n; j ++) bdist[i][j] = 1e9 + 8; for (i = 0; i < k; i ++) { pq.push ({0, {b[i].x, b[i].y}}); bdist[b[i].x][b[i].y] = 0; } while (!pq.empty ()) { t = pq.top (); pq.pop (); cdist = -t.first; cpos = t.second; cx = cpos.first; cy = cpos.second; if (bdist[cx][cy] < cdist) continue; for (i = 0; i < 4; i ++) { nx = cx + aa[i]; ny = cy + bb[i]; if (nx > n || nx <= 0) continue; if (ny > n || ny <= 0) continue; nd = cdist + mabs (h[cx][cy] - h[nx][ny]) * mabs (h[cx][cy] - h[nx][ny]) + 1; /// + cakes maybe ? if (bdist[nx][ny] <= nd) continue; bdist[nx][ny] = nd; bdir[nx][ny] = cc[i]; pq.push ({-nd, {nx, ny}}); } } /** for (i = 1; i <= n; i ++, fprintf (stderr, "\n")) for (j = 1; j <= n; j ++) fprintf (stderr, "%d ", bdist[i][j]); fprintf (stderr, "\n"); for (i = 1; i <= n; i ++, fprintf (stderr, "\n")) for (j = 1; j <= n; j ++) fprintf (stderr, "%d ", bdir[i][j]); **/ } void check_sol () { if (ans.score < crr.score) ans = crr; } void go_to_bakery () { while (bdist[crr.x][crr.y]) { crr.moves.push_back (bdir[crr.x][crr.y]); if (bdir[crr.x][crr.y] == U) { crr.tm += mabs (h[crr.x][crr.y] - h[crr.x - 1][crr.y]) * mabs (h[crr.x][crr.y] - h[crr.x - 1][crr.y]) + 1; crr.x --; continue; } if (bdir[crr.x][crr.y] == D) { crr.tm += mabs (h[crr.x][crr.y] - h[crr.x + 1][crr.y]) * mabs (h[crr.x][crr.y] - h[crr.x + 1][crr.y]) + 1; crr.x ++; continue; } if (bdir[crr.x][crr.y] == L) { crr.tm += mabs (h[crr.x][crr.y] - h[crr.x][crr.y - 1]) * mabs (h[crr.x][crr.y] - h[crr.x][crr.y - 1]) + 1; crr.y --; continue; } if (bdir[crr.x][crr.y] == R) { crr.tm += mabs (h[crr.x][crr.y] - h[crr.x][crr.y + 1]) * mabs (h[crr.x][crr.y] - h[crr.x][crr.y + 1]) + 1; crr.y ++; continue; } } } long long find_dist (int sx, int sy, int ex, int ey, long long ck) { long long f = 0, ac, bc, rrr, ka, kb; ///fprintf (stderr,"---\n"); while (sx != ex && sy != ey) { if (ck == 2) ///fprintf (stderr,"%d %d %d %d\n", sx, sy, ex, ey); if (f > (1LL << 33)) return (1LL << 33); if (sx < ex) { rrr = mabs (h[sx][sy] - h[sx + 1][sy]) + ck; ac = rrr * rrr + 1; ka = 1; } else { rrr = mabs (h[sx][sy] - h[sx - 1][sy]) + ck; ac = rrr * rrr + 1; ka = -1; } if (sy < ey) { rrr = mabs (h[sx][sy] - h[sx][sy + 1]) + ck; bc = rrr * rrr + 1; kb = 1; } else { rrr = mabs (h[sx][sy] - h[sx][sy - 1]) + ck; bc = rrr * rrr + 1; kb = -1; } if (ac < bc) { f += ac; sx += ka; } else { f += bc; sy += kb; } } while (sx != ex) { if (sx < ex) { rrr = mabs (h[sx][sy] - h[sx + 1][sy]) + ck; ac = rrr * rrr + 1; ka = 1; } else { rrr = mabs (h[sx][sy] - h[sx - 1][sy]) + ck; ac = rrr * rrr + 1; ka = -1; } f += ac; sx += ka; } while (sy != ey) { if (sy < ey) { rrr = mabs (h[sx][sy] - h[sx][sy + 1]) + ck; bc = rrr * rrr + 1; kb = 1; } else { rrr = mabs (h[sx][sy] - h[sx][sy - 1]) + ck; bc = rrr * rrr + 1; kb = -1; } f += bc; sy += kb; } return f; } inline void go (int ex, int ey, long long ck) { long long f = 0, ac, bc, rrr, ka, kb, sx = crr.x, sy = crr.y; while (sx != ex && sy != ey) { if (sx < ex) { rrr = mabs (h[sx][sy] - h[sx + 1][sy]) + ck; ac = rrr * rrr + 1; ka = 1; } else { rrr = mabs (h[sx][sy] - h[sx - 1][sy]) + ck; ac = rrr * rrr + 1; ka = -1; } if (sy < ey) { rrr = mabs (h[sx][sy] - h[sx][sy + 1]) + ck; bc = rrr * rrr + 1; kb = 1; } else { rrr = mabs (h[sx][sy] - h[sx][sy - 1]) + ck; bc = rrr * rrr + 1; kb = -1; } if (ac < bc) { crr.moves.push_back ((ka == 1) ? D : U); crr.tm += ac; sx += ka; } else { crr.moves.push_back ((kb == 1) ? R : L); crr.tm += bc; sy += kb; } } while (sx != ex) { if (sx < ex) { rrr = mabs (h[sx][sy] - h[sx + 1][sy]) + ck; ac = rrr * rrr + 1; ka = 1; } else { rrr = mabs (h[sx][sy] - h[sx - 1][sy]) + ck; ac = rrr * rrr + 1; ka = -1; } crr.moves.push_back ((ka == 1) ? D : U); sx += ka; crr.tm += ac; } while (sy != ey) { if (sy < ey) { rrr = mabs (h[sx][sy] - h[sx][sy + 1]) + ck; bc = rrr * rrr + 1; kb = 1; } else { rrr = mabs (h[sx][sy] - h[sx][sy - 1]) + ck; bc = rrr * rrr + 1; kb = -1; } crr.moves.push_back ((kb == 1) ? R : L); sy += kb; crr.tm += bc; } crr.x = ex; crr.y = ey; } inline int cakes_and_party () { long long d, d1, d2, d5, d10, d20, d30, d100, d500, d1500, d10000, d50000, bst = -1, ck = 0, as; while (p[pos].start + p[pos].len <= crr.tm) pos ++; while (pos < m) { if (bomb ()) return -1; d = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 1); if (crr.tm + d >= p[pos].start + p[pos].len) { pos ++; continue; } long long lc, rc, midc; d1 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 1); bst = ((p[pos].start + p[pos].len) - (crr.tm + d1)) * 1; as = 1; if (bomb ()) return -1; d5 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 5); if (crr.tm + d5 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d5)) * 5 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d5)) * 5; as = 5; } } if (bomb ()) return -1; d10 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 10); if (crr.tm + d10 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d10)) * 10 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d10)) * 10; as = 10; } } if (bomb ()) return -1; d20 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 20); if (crr.tm + d20 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d20)) * 20 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d20)) * 20; as = 20; } } d30 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y,30); if (crr.tm + d30 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d30)) * 30 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d30)) * 30; as = 30; } } d100 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 100); if (crr.tm + d100 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d100)) * 100 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d100)) * 100; as = 100; } } d500 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 500); if (crr.tm + d500 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d500)) * 500 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d500)) * 500; as = 500; } } d1500 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 5000); if (crr.tm + d1500 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d1500)) * 5000 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d1500)) * 5000; as = 5000; } } d10000 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 10000); if (crr.tm + d10000 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d10000)) * 10000 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d10000)) * 10000; as = 10000; } } d50000 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 50000); if (crr.tm + d50000 < p[pos].start + p[pos].len) { if (((p[pos].start + p[pos].len) - (crr.tm + d50000)) * 50000 > bst) { bst = ((p[pos].start + p[pos].len) - (crr.tm + d50000)) * 50000; as = 50000; } } crr.score += bst; crr.cakes = as; ///fprintf (stderr, "cakes = 1\n"); crr.moves.push_back (as); return pos; d10 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 10); d20 = find_dist (crr.x, crr.y, p[pos].x, p[pos].y, 20); } return -1; } void solve () { crr = sol (stx, sty, 0, 0, 0, tmp); int party_idx; while (ok ()) { ///fprintf (stderr, "%d %d\n", clock (), (int) CLOCKS_PER_SEC); ///fprintf (stderr, "%lf %d %lf\n", double (clock ()), CLOCKS_PER_SEC, double (double (clock ()) / CLOCKS_PER_SEC)); check_sol (); ///fprintf (stderr, "-- TIME %d\n", crr.tm); ///fprintf (stderr, "-- Here %d %d\n", crr.x, crr.y); go_to_bakery (); ///fprintf (stderr, "-- Went to bakery %d %d\n", crr.x, crr.y); party_idx = cakes_and_party (); if (party_idx == -1) break; go (p[party_idx].x, p[party_idx].y, crr.cakes); crr.tm = p[party_idx].start + p[party_idx].len; crr.moves.push_back (P); crr.moves.push_back (crr.cakes); crr.cakes = 0; pos ++; ///fprintf (stderr, "-- Im at the party %d %d\n", crr.x, crr.y); } return; } int main () { ans.score = -1; freopen ("party.in", "r", stdin); freopen ("party.out", "w", stdout); read (); init (); ///fprintf (stderr, "%d %d\n", clock (), (int) CLOCKS_PER_SEC); solve (); crr.print (); return 0; }