https://ac.nowcoder.com/acm/contest/21739/E
- There is a simpler way to solve this problem (enumerating all UDLR permutations). It took me 2 and a half hours to finally AC
Idea:
-
1. First of all, we can think that given a sequence of walking methods, no matter how the sequence is arranged, its end point must be determined. Therefore, if the bomb (mx,my) is at the starting point (0,0) or the end point (x,y), the result must be I m p o s s i b l e Impossible Impossible.
-
2. There is another I m p o s s i b l e Impossible The case of impossibility is when there are no steps in the X-axis direction( C n t R = 0 & & C n t L = 0 Cnt_R=0\&\& Cnt_L=0 CntR = 0 & & cntl = 0) and the bomb is on the only way in the Y-axis direction; When there are no steps in the Y-axis direction( C n t U = 0 & & C n t D = 0 Cnt_U=0\&\& Cnt_D=0 CntU = 0 & & cntd = 0) and the bomb is on the only way in the X-axis direction
-
3. Except for the above two cases, a sequence can always be found in the remaining cases so that the robot does not pass through the bomb. We can discuss the following cases:
-
a. The end point is not on the axis
We simplify the path into two types: first walking horizontally and then walking vertically and first walking vertically and then walking horizontally
This situation is relatively simple. You only need to judge whether the bomb is on any path, so don't take this path. For example, if the bomb is on 1, go 2; If the bomb is on 2 or somewhere else, go 1
-
b. The end point is on the axis
This situation seems simple, but it is actually more complex. For example, if the end point is on the Y axis, it means that the steps of L and R are equal. But first L or first R may affect the answer, so we need to make some judgments. For example, if the bomb is below the X axis, there will be no problem if we first U and then D; If the bomb is on the left of the y-axis, there will be no problem with R and l first. (there will be problems. We have screened out the second kind of impossibility). The language description here will be more troublesome. It should be easier to understand by looking directly at the code
-
-
4. Finally, pay attention to the sign, and then explain each situation clearly. It should be able to AC
code:
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map> #include<unordered_map> #include<set> //#pragma GCC optimize(2) //#pragma GCC optimize("inline") //#pragma GCC optimize("-fgcse") //#pragma GCC target("avx","sse2") //#pragma GCC optimize("-fgcse-lm") //#pragma GCC optimize("-fipa-sra") //#pragma GCC optimize("-ftree-pre") //#pragma GCC optimize("-ftree-vrp") //#pragma GCC optimize("-fpeephole2") //#pragma GCC optimize("-ffast-math") //#pragma GCC optimize("-fsched-spec") //#pragma GCC optimize("unroll-loops") using namespace std; #define ll long long #define PII pair<int,int> #define PLL pair<ll,ll> #define PIII pair<int,PII> #define PLLL pair<ll,PLL> #define fi first #define se second #define pb push_back #define debug(a) cout << #a << " " << a << '\n'; const int N = 1e5 + 5; const int M = 1e5 + 5; const ll INF = 0x3f3f3f3f3f3f3f3f; const ll mod = 1e9 + 7; ll mx, my; bool tong(ll x, ll y) {//Judge whether two numbers have the same number if (x == 0 || y == 0)return true; if (x >= 0 && y >= 0)return true; if (x <= 0 && y <= 0)return true; return false; } void solve() { map<char, ll> mp; cin >> mx >> my; string path; cin >> path; int len = path.length(); for (int i = 0; i < len; i++) { if (path[i] == 'L')mp['L']++; else if (path[i] == 'R')mp['R']++; else if (path[i] == 'U')mp['U']++; else if (path[i] == 'D')mp['D']++; } ll x = mp['R'] - mp['L'];//Calculation end point (must reach) ll y = mp['U'] - mp['D']; //The location of the bomb is at the end or starting point if ((mx == x && my == y) || (mx == 0 && my == 0)) { cout << "Impossible\n"; } //It can only move on the Y axis. The bomb is on the only way else if ((!mp['L'] && !mp['R']) && (tong(my, y) && abs(my) <= abs(y) && mx == 0)) { cout << "Impossible\n"; } //It can only move on the X axis. The bomb is on the only way else if ((!mp['U'] && !mp['D']) && (tong(mx, x) && abs(mx) <= abs(x) && my == 0)) { cout << "Impossible\n"; } else { //L and R finally offset if (x == 0) { string ans; if (mx > 0) {//The bomb is on the right side of the Y axis, then go to the left first for (int i = 0; i < mp['L']; i++) ans += 'L'; if (my < 0) { //The bomb is under the X-axis, so go up first for (int i = 0; i < mp['U']; i++) ans += 'U'; for (int i = 0; i < mp['D']; i++) ans += 'D'; } else { for (int i = 0; i < mp['D']; i++) ans += 'D'; for (int i = 0; i < mp['U']; i++) ans += 'U'; } for (int i = 0; i < mp['R']; i++) ans += 'R'; } else { for (int i = 0; i < mp['R']; i++) ans += 'R'; if (my < 0) { for (int i = 0; i < mp['U']; i++) ans += 'U'; for (int i = 0; i < mp['D']; i++) ans += 'D'; } else { for (int i = 0; i < mp['D']; i++) ans += 'D'; for (int i = 0; i < mp['U']; i++) ans += 'U'; } for (int i = 0; i < mp['L']; i++) ans += 'L'; } cout << ans << '\n'; return; } //U and D finally offset if (y == 0) { string ans; if (my > 0) { //The bomb is on the upper side of the X-axis, then go down first for (int i = 0; i < mp['D']; i++) ans += 'D'; if (mx < 0) {//The bomb is on the left side of the Y axis, then go to the right first for (int i = 0; i < mp['R']; i++) ans += 'R'; for (int i = 0; i < mp['L']; i++) ans += 'L'; } else { for (int i = 0; i < mp['L']; i++) ans += 'L'; for (int i = 0; i < mp['R']; i++) ans += 'R'; } for (int i = 0; i < mp['U']; i++) ans += 'U'; } else { for (int i = 0; i < mp['U']; i++) ans += 'U'; if (mx < 0) { for (int i = 0; i < mp['R']; i++) ans += 'R'; for (int i = 0; i < mp['L']; i++) ans += 'L'; } else { for (int i = 0; i < mp['L']; i++) ans += 'L'; for (int i = 0; i < mp['R']; i++) ans += 'R'; } for (int i = 0; i < mp['D']; i++) ans += 'D'; } cout << ans << '\n'; return; } //The end point is not on the coordinate axis. You can go by horizontal first and then vertical or vertical first and then horizontal if ((my == 0 || mx == x)) {//If the bomb is not in the way of first horizontal and then vertical, go first vertical and then horizontal string ans; for (int i = 0; i < mp['U']; i++) ans += 'U'; for (int i = 0; i < mp['D']; i++) ans += 'D'; for (int i = 0; i < mp['L']; i++) ans += 'L'; for (int i = 0; i < mp['R']; i++) ans += 'R'; cout << ans << '\n'; } else { string ans; for (int i = 0; i < mp['L']; i++) ans += 'L'; for (int i = 0; i < mp['R']; i++) ans += 'R'; for (int i = 0; i < mp['U']; i++) ans += 'U'; for (int i = 0; i < mp['D']; i++) ans += 'D'; cout << ans << '\n'; } } } int main() { ios::sync_with_stdio(false); #ifdef LOCAL int begin_time = clock(); freopen("../input.txt", "r", stdin); // freopen("../output.txt", "w", stdout); #endif int T = 1; cin >> T; for (int cas = 1; cas <= T; cas++) { #ifdef LOCAL printf("Case #%d: ", cas); #endif solve(); } #ifdef LOCAL int end_time = clock(); printf("\nRun time: %.2lf ms", (double) (end_time - begin_time) / CLOCKS_PER_SEC * 1000); #endif return 0; }