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: Wrong Answer)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Program
{
    public class ABC051C
    {
        static class Console_
        {
            private static Queue<string> param = new Queue<string>();
            public static int NextInt() => int.Parse(NextString());
            public static string NextString()
            {
                if (param.Count == 0) foreach (var item in Console.ReadLine().Split(' ')) param.Enqueue(item);
                return param.Dequeue();
            }
        }
        static public void Main(string[] args)
        {
            var sx = Console_.NextInt();
            var sy = Console_.NextInt();
            var tx = Console_.NextInt();
            var ty = Console_.NextInt();

            var algo = new AStar();

            MyNode snode = null;
            MyNode gnode = null;

            var nodeTable = new MyNode[tx - sx + 3, ty - sy + 3];
            for (int i = 0; i <= tx - sx + 2; ++i)
            {
                for (int j = 0; j <= ty - sy + 2; ++j)
                {
                    var node = new MyNode();
                    node.x = i;
                    node.y = j;
                    node.h = Math.Abs(tx - sx + 1 - i) + Math.Abs(ty - sy + 1 - j);
                    node.f = Math.Abs(1 - i) + Math.Abs(1 - j) + node.h;
                    algo.AddNode(node);

                    if (i == 1 && j == 1)
                    {
                        snode = node;
                    }
                    if (i == tx - sx + 1 && j == ty - sy + 1)
                    {
                        gnode = node;
                    }

                    nodeTable[i, j] = node;
                    if (i >= 1)
                    {
                        nodeTable[i - 1, j].neighbor.Add(node);
                        node.neighbor.Add(nodeTable[i - 1, j]);
                    }
                    if (j >= 1)
                    {
                        nodeTable[i, j - 1].neighbor.Add(node);
                        node.neighbor.Add(nodeTable[i, j - 1]);
                    }
                }
            }
            gnode.isGoal = true;
            algo.Reset();
            var procNode = algo.GetPath(snode) as MyNode;
            var outList = new List<string>();
            while (procNode.parent != null)
            {
                var nextProcNode = procNode.parent as MyNode;
                procNode.neighbor.Remove(nextProcNode);
                nextProcNode.neighbor.Remove(procNode);
                if (nextProcNode.x < procNode.x)
                {
                    outList.Add("R");
                }
                else if (nextProcNode.x > procNode.x)
                {
                    outList.Add("L");
                }
                else if (nextProcNode.y < procNode.y)
                {
                    outList.Add("U");
                }
                else
                {
                    outList.Add("D");
                }
                procNode = nextProcNode;
            }
            for (int i = 0; i <= tx - sx + 2; ++i)
            {
                for (int j = 0; j <= ty - sy + 2; ++j)
                {
                    nodeTable[i, j].h = Math.Abs(1 - i) + Math.Abs(1 - j);
                    nodeTable[i, j].f = Math.Abs(tx - sx + 1 - i) + Math.Abs(ty - sy + 1 - j) + nodeTable[i, j].h;
                }
            }
            gnode.isGoal = false;
            snode.isGoal = true;
            algo.Reset();
            procNode = algo.GetPath(gnode) as MyNode;
            while (procNode.parent != null)
            {
                var nextProcNode = procNode.parent as MyNode;
                procNode.neighbor.Remove(nextProcNode);
                nextProcNode.neighbor.Remove(procNode);
                if (nextProcNode.x < procNode.x)
                {
                    outList.Add("R");
                }
                else if (nextProcNode.x > procNode.x)
                {
                    outList.Add("L");
                }
                else if (nextProcNode.y < procNode.y)
                {
                    outList.Add("U");
                }
                else
                {
                    outList.Add("D");
                }
                procNode = nextProcNode;
            }
            for (int i = 0; i <= tx - sx + 2; ++i)
            {
                for (int j = 0; j <= ty - sy + 2; ++j)
                {
                    nodeTable[i, j].h = Math.Abs(tx - sx + 1 - i) + Math.Abs(ty - sy + 1 - j);
                    nodeTable[i, j].f = Math.Abs(1 - i) + Math.Abs(1 - j) + nodeTable[i, j].h;
                }
            }
            snode.isGoal = false;
            gnode.isGoal = true;
            algo.Reset();
            procNode = algo.GetPath(snode) as MyNode;
            while (procNode.parent != null)
            {
                var nextProcNode = procNode.parent as MyNode;
                procNode.neighbor.Remove(nextProcNode);
                nextProcNode.neighbor.Remove(procNode);
                if (nextProcNode.x < procNode.x)
                {
                    outList.Add("R");
                }
                else if (nextProcNode.x > procNode.x)
                {
                    outList.Add("L");
                }
                else if (nextProcNode.y < procNode.y)
                {
                    outList.Add("U");
                }
                else
                {
                    outList.Add("D");
                }
                procNode = nextProcNode;
            }
            for (int i = 0; i <= tx - sx + 2; ++i)
            {
                for (int j = 0; j <= ty - sy + 2; ++j)
                {
                    nodeTable[i, j].h = Math.Abs(1 - i) + Math.Abs(1 - j);
                    nodeTable[i, j].f = Math.Abs(tx - sx + 1 - i) + Math.Abs(ty - sy + 1 - j) + nodeTable[i, j].h;
                }
            }
            gnode.isGoal = false;
            snode.isGoal = true;
            algo.Reset();
            procNode = algo.GetPath(gnode) as MyNode;
            while (procNode.parent != null)
            {
                var nextProcNode = procNode.parent as MyNode;
                procNode.neighbor.Remove(nextProcNode);
                nextProcNode.neighbor.Remove(procNode);
                if (nextProcNode.x < procNode.x)
                {
                    outList.Add("R");
                }
                else if (nextProcNode.x > procNode.x)
                {
                    outList.Add("L");
                }
                else if (nextProcNode.y < procNode.y)
                {
                    outList.Add("U");
                }
                else
                {
                    outList.Add("D");
                }
                procNode = nextProcNode;
            }
            foreach (var item in outList)
            {
                Console.Write(item);
            }
            Console.WriteLine("");
        }

        class MyNode : AStar.Node
        {
            public int x;
            public int y;
        }

        class AStar
        {
            public class Node
            {
                public double f = 0;
                public double h = 0;
                public IList<Node> neighbor = new List<Node>();
                public bool isGoal = false;
                public bool isOpen = false;
                public bool isClose = false;
                public Node parent = null;
                public uint id;
            }
            private class NodeComparer : IComparer<uint>
            {
                private IDictionary<uint, Node> dic;
                public NodeComparer(IDictionary<uint, Node> dic)
                {
                    this.dic = dic;
                }
                int IComparer<uint>.Compare(uint x, uint y)
                {
                    return dic[x].f.CompareTo(dic[y].f);
                }
            }
            private PriorityQueue<uint> openList;
            private IDictionary<uint, Node> dic = new Dictionary<uint, Node>();
            private uint unique = 0;
            public void AddNode(Node n)
            {
                n.id = ++unique;
                dic[n.id] = n;
            }
            public void Reset()
            {
                openList = new PriorityQueue<uint>(2000000, new NodeComparer(dic));
                foreach (var item in dic)
                {
                    item.Value.isOpen = false;
                    item.Value.isClose = false;
                    item.Value.parent = null;
                }
            }
            public Node GetPath(Node startNode)
            {
                startNode.isOpen = true;
                openList.Push(startNode.id);
                while (true)
                {
                    if (openList.Count() == 0)
                    {
                        return null;
                    }
                    var node = dic[openList.Pop()];
                    if (node.isClose)
                    {
                        continue;
                    }
                    if (node.isGoal)
                    {
                        return node;
                    }
                    node.isOpen = false;
                    node.isClose = true;
                    foreach (var children in node.neighbor)
                    {
                        var fd = node.f - node.h + 1 + children.h;
                        if (!children.isOpen && !children.isClose)
                        {
                            children.f = fd;
                            children.parent = node;
                            children.isOpen = true;
                            children.isClose = false;
                            openList.Push(children.id);
                        }
                        else if (children.f > fd)
                        {
                            children.f = fd;
                            children.parent = node;
                            children.isOpen = true;
                            children.isClose = false;
                            openList.Push(children.id);
                        }
                    }
                }
            }
            private class PriorityQueue<T> where T : IComparable
            {
                private IComparer<T> _comparer = null;
                private int _type = 0;

                private T[] _heap;
                private int _sz = 0;

                private int _count = 0;

                /// <summary>
                /// Priority Queue with custom comparer
                /// </summary>
                public PriorityQueue(int maxSize, IComparer<T> comparer)
                {
                    _heap = new T[maxSize];
                    _comparer = comparer;
                }

                /// <summary>
                /// Priority queue
                /// </summary>
                /// <param name="maxSize">max size</param>
                /// <param name="type">0: asc, 1:desc</param>
                public PriorityQueue(int maxSize, int type = 0)
                {
                    _heap = new T[maxSize];
                    _type = type;
                }

                private int Compare(T x, T y)
                {
                    if (_comparer != null) return _comparer.Compare(x, y);
                    return _type == 0 ? x.CompareTo(y) : y.CompareTo(x);
                }

                public void Push(T x)
                {
                    _count++;

                    //node number
                    var i = _sz++;

                    while (i > 0)
                    {
                        //parent node number
                        var p = (i - 1) / 2;

                        if (Compare(_heap[p], x) <= 0) break;

                        _heap[i] = _heap[p];
                        i = p;
                    }

                    _heap[i] = x;
                }

                public T Pop()
                {
                    _count--;

                    T ret = _heap[0];
                    T x = _heap[--_sz];

                    int i = 0;
                    while (i * 2 + 1 < _sz)
                    {
                        //children
                        int a = i * 2 + 1;
                        int b = i * 2 + 2;

                        if (b < _sz && Compare(_heap[b], _heap[a]) < 0) a = b;

                        if (Compare(_heap[a], x) >= 0) break;

                        _heap[i] = _heap[a];
                        i = a;
                    }

                    _heap[i] = x;

                    return ret;
                }

                public int Count()
                {
                    return _count;
                }

                public T Peek()
                {
                    return _heap[0];
                }

                public bool Contains(T x)
                {
                    for (int i = 0; i < _sz; i++) if (x.Equals(_heap[i])) return true;
                    return false;
                }

                public void Clear()
                {
                    while (this.Count() > 0) this.Pop();
                }

                public IEnumerator<T> GetEnumerator()
                {
                    var ret = new List<T>();

                    while (this.Count() > 0)
                    {
                        ret.Add(this.Pop());
                    }

                    foreach (var r in ret)
                    {
                        this.Push(r);
                        yield return r;
                    }
                }

                public T[] ToArray()
                {
                    T[] array = new T[_sz];
                    int i = 0;

                    foreach (var r in this)
                    {
                        array[i++] = r;
                    }

                    return array;
                }
            }
        }
    }
}