Problem:
Score : 300 points

Problem Statement

Dolphin resides in two-dimensional Cartesian plane, with the positive x-axis pointing right and the positive y-axis pointing up.

Currently, he is located at the point (sx,sy). In each second, he can move up, down, left or right by a distance of 1.

Here, both the x- and y-coordinates before and after each movement must be integers.

He will first visit the point (tx,ty) where sx < tx and sy < ty, then go back to the point (sx,sy), then visit the point (tx,ty) again, and lastly go back to the point (sx,sy).

Here, during the whole travel, he is not allowed to pass through the same point more than once, except the points (sx,sy) and (tx,ty).

Under this condition, find a shortest path for him.

Constraints

-1000 ≤ sx < tx ≤ 1000

-1000 ≤ sy < ty ≤ 1000

sx,sy,tx and ty are integers.

Input

The input is given from Standard Input in the following format:

sx sy tx ty

Output

Print a string S that represents a shortest path for Dolphin.

The i-th character in S should correspond to his i-th movement.

The directions of the movements should be indicated by the following characters:

U: Up

D: Down

L: Left

R: Right

If there exist multiple shortest paths under the condition, print any of them.

Sample Input 1

0 0 1 2

Sample Output 1

UURDDLLUUURRDRDDDLLU

One possible shortest path is:

Going from (sx,sy) to (tx,ty) for the first time: (0,0) → (0,1) → (0,2) → (1,2)

Going from (tx,ty) to (sx,sy) for the first time: (1,2) → (1,1) → (1,0) → (0,0)

Going from (sx,sy) to (tx,ty) for the second time: (0,0) → (-1,0) → (-1,1) → (-1,2) → (-1,3) → (0,3) → (1,3) → (1,2)

Going from (tx,ty) to (sx,sy) for the second time: (1,2) → (2,2) → (2,1) → (2,0) → (2,-1) → (1,-1) → (0,-1) → (0,0)

Sample Input 2

-2 -2 1 1

Sample Output 2

UURRURRDDDLLDLLULUUURRURRDDDLLDL

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using static System.Math;

namespace CompetitionPrograming2
{
    public sealed class Program : BaseProgram
    {
        public static int[][] shortestCost;
        public static void Main(string[] args) { using (var sc = new SetConsole()) { Solve(); } }
        public static void Solve()
        {
            var input = GetArray<int>();
            var sx = input[0] + 1000;
            var sy = input[1] + 1000;
            var tx = input[2] + 1000;
            var ty = input[3] + 1000;
            var result = new List<string>();
            var passedMass = new HashSet<Pos>();
            var route = Bfs(new int[] { sx, sy }, new int[] { tx, ty }, passedMass);
            foreach (var r in route)
            {
                passedMass.Add(new Pos { X = r.Item2[0], Y = r.Item2[1] });
                result.Add(r.Item1);
            }
            route = Bfs(new int[] { tx, ty }, new int[] { sx, sy }, passedMass);
            foreach (var r in route)
            {
                passedMass.Add(new Pos { X = r.Item2[0], Y = r.Item2[1] });
                result.Add(r.Item1);
            }
            route = Bfs(new int[] { sx, sy }, new int[] { tx, ty }, passedMass);
            foreach (var r in route)
            {
                passedMass.Add(new Pos { X = r.Item2[0], Y = r.Item2[1] });
                result.Add(r.Item1);
            }
            route = Bfs(new int[] { tx, ty }, new int[] { sx, sy }, passedMass);
            foreach (var r in route)
            {
                passedMass.Add(new Pos { X = r.Item2[0], Y = r.Item2[1] });
                result.Add(r.Item1);
            }
            Write(result.StringJoin(""));
        }

        public static List<Tuple<string, int[]>> Bfs(int[] start, int[] end, HashSet<Pos> passedMass)
        {
            shortestCost = new int[2002][];
            for (int i = 0; i < shortestCost.Length; i++) { shortestCost[i] = Enumerable.Repeat(SafeInf(100), 2002).ToArray(); }
            shortestCost[start[0]][start[1]] = 0;

            var que = new Queue<int[]>();
            que.Enqueue(start);
            while (que.Any())
            {
                var current = que.Dequeue();
                var cost = shortestCost[current[0]][current[1]];

                var up = new int[] { current[0], current[1] + 1 };
                if ((!passedMass.Contains(new Pos { X = up[0], Y = up[1] }) || CheckEqual(up, end)) && !CheckOutOfRange(up, start, end) && shortestCost[up[0]][up[1]] > cost + 1)
                {
                    shortestCost[up[0]][up[1]] = cost + 1;
                    que.Enqueue(up);
                }

                var down = new int[] { current[0], current[1] - 1 };
                if ((!passedMass.Contains(new Pos { X = down[0], Y = down[1] }) || CheckEqual(down, end)) && !CheckOutOfRange(down, start, end) && shortestCost[down[0]][down[1]] > cost + 1)
                {
                    shortestCost[down[0]][down[1]] = cost + 1;
                    que.Enqueue(down);
                }

                var right = new int[] { current[0] + 1, current[1] };
                if ((!passedMass.Contains(new Pos { X = right[0], Y = right[1] }) || CheckEqual(right, end)) && !CheckOutOfRange(right, start, end) && shortestCost[right[0]][right[1]] > cost + 1)
                {
                    shortestCost[right[0]][right[1]] = cost + 1;
                    que.Enqueue(right);
                }

                var left = new int[] { current[0] - 1, current[1] };
                if ((!passedMass.Contains(new Pos { X = left[0], Y = left[1] }) || CheckEqual(left, end)) && !CheckOutOfRange(left, start, end) && shortestCost[left[0]][left[1]] > cost + 1)
                {
                    shortestCost[left[0]][left[1]] = cost + 1;
                    que.Enqueue(left);
                }
            }

            var shortestRoute = new Stack<Tuple<string, int[]>>();
            shortestRoute.Push(Tuple.Create("", end));
            var count = shortestCost[end[0]][end[1]];
            for (int i = 0; i < count; i++)
            {
                // 終わりから見ての方向
                var up = new int[] { shortestRoute.Peek().Item2[0], shortestRoute.Peek().Item2[1] + 1 };
                var down = new int[] { shortestRoute.Peek().Item2[0], shortestRoute.Peek().Item2[1] - 1 };
                var right = new int[] { shortestRoute.Peek().Item2[0] + 1, shortestRoute.Peek().Item2[1] };
                var left = new int[] { shortestRoute.Peek().Item2[0] - 1, shortestRoute.Peek().Item2[1] };

                // スタートから見ての方向
                if (!CheckOutOfRange(up, start, end) && ConvertCoordinateToCost(shortestCost, up) == shortestCost[end[0]][end[1]] - i - 1)
                {
                    shortestRoute.Push(Tuple.Create("D", up));
                }
                else if (!CheckOutOfRange(down, start, end) && ConvertCoordinateToCost(shortestCost, down) == shortestCost[end[0]][end[1]] - i - 1)
                {
                    shortestRoute.Push(Tuple.Create("U", down));
                }
                else if (!CheckOutOfRange(right, start, end) && ConvertCoordinateToCost(shortestCost, right) == shortestCost[end[0]][end[1]] - i - 1)
                {
                    shortestRoute.Push(Tuple.Create("L", right));
                }
                else if (!CheckOutOfRange(left, start, end) && ConvertCoordinateToCost(shortestCost, left) == shortestCost[end[0]][end[1]] - i - 1)
                {
                    shortestRoute.Push(Tuple.Create("R", left));
                }
            }
            return shortestRoute.ToList();
        }

        public static bool CheckEqual(int[] xy1, int[] xy2)
        {
            return xy1[0] == xy2[0] && xy1[1] == xy2[1];
        }

        public static bool CheckOutOfRange(int[] xy1, int[] start, int[] end)
        {
            var minX = Min(start[0], end[0]);
            var maxX = Max(start[0], end[0]);
            var minY = Min(start[1], end[1]);
            var maxY = Max(start[1], end[1]);
            return xy1[0] > Min(maxX, 2001) || xy1[1] > Min(maxY, 2001) || xy1[0] < Max(minX, 0) || xy1[1] < Max(minY, 0);
        }

        public static int ConvertCoordinateToCost(int[][] map, int[] xy)
        {
            return map[xy[0]][xy[1]];
        }

        public struct Pos
        {
            public int X { get; set; }
            public int Y { get; set; }
        }
    }

    public abstract class BaseProgram
    {
        protected readonly static long divisor = 1000000007;
        protected static int SafeInf(int margin = 1) => int.MaxValue - margin;
        protected static void Write(object obj) => Console.WriteLine(obj);
        protected static string GetString()
        {
            var str = Console.ReadLine();
            if (str == null) { throw new NullReferenceException("標準入力がnullです Solveメソッド内の解答コードが間違っています"); }
            return str;
        }
        protected static T GetNumber<T>() where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
        {
            var str = GetString();
            var t = typeof(T);
            if ((t == typeof(byte)))
            {
                return (T)(object)str.ToByte();
            }
            else if (t == typeof(int))
            {
                return (T)(object)str.ToInt();
            }
            else if (t == typeof(long))
            {
                return (T)(object)str.ToLong();
            }
            else if (t == typeof(double))
            {
                return (T)(object)str.ToDouble();
            }
            else if (t == typeof(decimal))
            {
                return (T)(object)str.ToDecimal();
            }
            else if (t == typeof(BigInteger))
            {
                return (T)(object)str.ToBigInteger();
            }
            throw new NotSupportedException();
        }
        protected static T[] GetArray<T>() where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
        {
            return GetString().ToArray<T>();
        }
        protected static TResult[] GetArray<TResult>(Func<string, TResult> selector)
        {
            return (TResult[])(object)GetString().Split().Select(selector).ToArray();
        }
        protected static void Swap<T>(ref T item1, ref T item2)
        {
            var tmp = item1;
            item1 = item2;
            item2 = tmp;
        }
        protected sealed class SetConsole : IDisposable
        {
            readonly StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
            public SetConsole()
            {
                sw.AutoFlush = false;
                Console.SetOut(sw);
            }
            public void Dispose()
            {
                Console.Out.Flush();
                sw.AutoFlush = true;
                Console.SetOut(sw);
            }
        }
    }
    public static class ExtentionsLibrary
    {
        public static T[,] CopyArray<T>(this T[,] array)
        {
            var firstDimentionLength = array.GetLength(0);
            var secondDimentionLength = array.GetLength(1);
            var newDArray = new T[firstDimentionLength, secondDimentionLength];
            Array.Copy(array, newDArray, firstDimentionLength * secondDimentionLength);
            return newDArray;
        }
        public static T[] ToArray<T>(this string str) where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
        {
            if (typeof(T) == typeof(string)) { return (T[])(object)str.Split(); }

            return str.ConvertEnumerator<T>().ToArray();
        }
        public static IEnumerable<T> ConvertEnumerator<T>(this string str) where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
        {
            var t = typeof(T);
            if (t == typeof(byte))
            {
                return (IEnumerable<T>)str.Split().Select(byte.Parse);
            }
            if (t == typeof(int))
            {
                return (IEnumerable<T>)str.Split().Select(int.Parse);
            }
            if (t == typeof(long))
            {
                return (IEnumerable<T>)str.Split().Select(long.Parse);
            }
            if (t == typeof(double))
            {
                return (IEnumerable<T>)str.Split().Select(double.Parse);
            }
            if (t == typeof(decimal))
            {
                return (IEnumerable<T>)str.Split().Select(decimal.Parse);
            }
            if (t == typeof(BigInteger))
            {
                return (IEnumerable<T>)str.Split().Select(BigInteger.Parse);
            }
            throw new NotSupportedException();
        }
        public static byte ToByte(this string str) => byte.Parse(str);
        public static byte ToByte(this char chr) => byte.Parse(chr.ToString());
        public static int ToInt(this string str) => int.Parse(str);
        public static int ToInt(this char chr) => int.Parse(chr.ToString());
        public static long ToLong(this string str) => long.Parse(str);
        public static double ToDouble(this string str) => double.Parse(str);
        public static decimal ToDecimal(this string str) => decimal.Parse(str);
        public static BigInteger ToBigInteger(this string str) => BigInteger.Parse(str);
        public static DateTime ToDateTime(this string str) => DateTime.Parse(str);
        public static string StringJoin(this object[] array, string separator = "") => string.Join(separator, array);
        public static string StringJoin<T>(this IEnumerable<T> collection, string separator = "") => string.Join(separator, collection.Select(c => c.ToString()));
        public static int LowerBound<T>(this IReadOnlyList<T> a, T v) => LowerBound(a, v, Comparer<T>.Default);
        public static int LowerBound<T>(this IReadOnlyList<T> a, T v, Comparer<T> cmp)
        {
            var l = 0;
            var r = a.Count - 1;
            while (l <= r)
            {
                var mid = l + (r - l) / 2;
                var result = cmp.Compare(a[mid], v);
                if (result == -1)
                {
                    l = mid + 1;
                }
                else
                {
                    r = mid - 1;
                }
            }
            return l;
        }
        public static int UpperBound<T>(this IReadOnlyList<T> a, T v) => UpperBound(a, v, Comparer<T>.Default);
        public static int UpperBound<T>(this IReadOnlyList<T> a, T v, Comparer<T> cmp)
        {
            var l = 0;
            var r = a.Count - 1;
            while (l <= r)
            {
                var mid = l + (r - l) / 2;
                var res = cmp.Compare(a[mid], v);
                if (res <= 0) l = mid + 1;
                else r = mid - 1;
            }
            return l;
        }
    }
    public sealed class Settings
    {
        public enum Priority : byte
        {
            Smaller = 0,
            Larger = 1
        }
    }
}