Skip to content

Commit a690cad

Browse files
committed
20190601
1 parent 4dbe216 commit a690cad

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

TangoTangoInsurrectionUVa10618.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include<cstdio>
2+
#include<cstring>
3+
#include<cassert>
4+
5+
const int UP = 0;
6+
const int LEFT = 1;
7+
const int RIGHT = 2;
8+
const int DOWN = 3;
9+
10+
const int maxn = 70 + 5;
11+
12+
// d[i][a][b][s] means the minimal future energy when you already tapped i notes
13+
// your left foot at a, right foot at b, last foot is s
14+
int d[maxn][4][4][3];
15+
16+
// if the optimal strategy is to move foot f(0~2) to position t, action=f*4+t
17+
int action[maxn][4][4][3];
18+
19+
char seq[maxn], pos[256], footch[] = ".LR";
20+
21+
// energy needed to move a foot FOR THE SECOND TIME, from a to ta
22+
int energy(int a, int ta) {
23+
if(a == ta) return 3;
24+
if(a + ta == 3) return 7; // across
25+
return 5; // adjacent
26+
}
27+
28+
int energy(int i, int a, int b, int s, int f, int t, int& ta, int& tb) {
29+
ta = a; tb = b;
30+
if(f == 1) ta = t;
31+
else if(f == 2) tb = t;
32+
33+
// check target arrows
34+
if(ta == tb) return -1;
35+
if(ta == RIGHT && tb == LEFT) return -1;
36+
if(a == RIGHT && tb != b) return -1; // you can't move you right foot before your left foot comes back
37+
if(b == LEFT && ta != a) return -1;
38+
39+
// compute energy
40+
int e;
41+
if(f == 0) e = 0; // no move
42+
else if(f != s) e = 1; // alternative foot, low energy
43+
else {
44+
if(f == 1) e = energy(a, ta);
45+
else e = energy(b, tb);
46+
}
47+
return e;
48+
}
49+
50+
// update state (i,a,b,s). foot f is moved to t
51+
void update(int i, int a, int b, int s, int f, int t) {
52+
int ta, tb;
53+
int e = energy(i, a, b, s, f, t, ta, tb);
54+
if(e < 0) return; // invalid
55+
56+
int cost = d[i+1][ta][tb][f] + e;
57+
int& ans = d[i][a][b][s];
58+
if(cost < ans) {
59+
ans = cost;
60+
action[i][a][b][s] = f * 4 + t;
61+
}
62+
}
63+
64+
int main() {
65+
pos['U'] = 0; pos['L'] = 1; pos['R'] = 2; pos['D'] = 3;
66+
67+
while(scanf("%s", seq) == 1) {
68+
if(seq[0] == '#') break;
69+
int n = strlen(seq);
70+
memset(d, 0, sizeof(d));
71+
for(int i = n-1; i >= 0; i--)
72+
for(int a = 0; a < 4; a++)
73+
for(int b = 0; b < 4; b++) if(a != b)
74+
for(int s = 0; s < 3; s++) {
75+
d[i][a][b][s] = 10*n;
76+
if(seq[i] == '.') {
77+
update(i, a, b, s, 0, 0); // no move
78+
for(int t = 0; t < 4; t++) {
79+
update(i, a, b, s, 1, t); // move left foot
80+
update(i, a, b, s, 2, t); // move right foot
81+
}
82+
} else {
83+
update(i, a, b, s, 1, pos[seq[i]]); // move left foot
84+
update(i, a, b, s, 2, pos[seq[i]]); // move right foot
85+
}
86+
}
87+
88+
// print solution
89+
int a = LEFT, b = RIGHT, s = 0; // d[0][1][2][0] is out answer
90+
for(int i = 0; i < n; i++) {
91+
int f = action[i][a][b][s] / 4;
92+
int t = action[i][a][b][s] % 4;
93+
printf("%c", footch[f]);
94+
s = f;
95+
if(f == 1) a = t;
96+
else if(f == 2) b = t;
97+
}
98+
printf("\n");
99+
}
100+
return 0;
101+
}

0 commit comments

Comments
 (0)