The 45th international undergraduate Programming Competition (ICPC) Asian regional competition (Nanjing) E.Evil Coordinate (classified discussion + simulation)

Posted by vivekjain on Wed, 13 Oct 2021 16:42:16 +0200

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;
}

Topics: C++ Algorithm acm