Problem:
Problem C: Numeral System

Prof. Hachioji has devised a new numeral system of
integral numbers with four lowercase letters "m", "c", "x", "i"
and with eight digits "2", "3", "4", "5", "6", "7", "8", "9".
He doesn't use digit "0" nor digit "1" in this system.

The letters "m", "c", "x" and "i" correspond to 1000, 100, 10 and 1,
respectively,
and the digits "2", ...,"9" correspond to 2, ..., 9, respectively.
This system has nothing to do with the Roman numeral system.

For example,
character strings

"5m2c3x4i", "m2c4i" and "5m2c3x"

correspond to the integral numbers
5234 (=5*1000+2*100+3*10+4*1),
1204 (=1000+2*100+4*1),
and 5230 (=5*1000+2*100+3*10),
respectively.
The parts of strings in the above example, "5m", "2c", "3x" and "4i"
represent 5000 (=5*1000), 200 (=2*100), 30 (=3*10) and 4 (=4*1),
respectively.

Each of the letters "m", "c", "x" and "i" may
be prefixed by one of the digits
"2", "3", ..., "9".
In that case, the prefix digit and the letter are regarded
as a pair.
A pair that consists of a prefix digit and a letter
corresponds to an integer that is equal to
the original value of the letter multiplied by
the value of the prefix digit.

For each letter "m", "c", "x" and "i",
the number of its occurrence in a string is at most one.
When it has a prefix digit, it should appear together with the prefix digit.
The letters "m", "c", "x" and "i" must appear in this order, from left to right.
Moreover, when a digit exists in a string,
it should appear as the prefix digit of the following letter.
Each letter may be omitted in a string, but
the whole string must not be empty.
A string made in this manner is called an MCXI-string.

An MCXI-string corresponds to a positive integer
that is the sum of the values of the letters
and those of the pairs contained in it as mentioned above.
The positive integer corresponding to an MCXI-string is called its
MCXI-value.
Moreover, given an integer from 1 to 9999,
there is a unique MCXI-string whose MCXI-value is equal
to the given integer.
For example,
the MCXI-value of an MCXI-string "m2c4i" is
1204 that is equal to 1000 + 2*100 + 4*1.
There are no MCXI-strings but "m2c4i" that correspond to 1204.
Note
that strings "1m2c4i", "mcc4i", "m2c0x4i", and "2cm4i" are
not valid MCXI-strings.
The reasons are use of "1",
multiple occurrences of "c", use of "0", and the wrong order of "c" and "m",
respectively.

Your job is to write a program for Prof. Hachioji
that reads two MCXI-strings,
computes the sum of their MCXI-values, and
prints the MCXI-string corresponding to the result.

Input

The input is as follows.
The first line contains a positive integer n (<= 500) that
indicates the number of the following lines.
The k+1 th line is the specification of
the k th computation (k=1, ..., n).

n

specification1

specification2

...

specificationn

Each specification is described in a line:

MCXI-string1 MCXI-string2

The two MCXI-strings are separated by a space.

You may assume that the sum of the two MCXI-values
of the two MCXI-strings in each specification
is less than or equal to 9999.

Output

For each specification,
your program should print an MCXI-string in a line.
Its MCXI-value should be the sum of the two MCXI-values
of the MCXI-strings in the specification.
No other characters should appear in the output.

Sample Input

10
xi x9i
i 9i
c2x2i 4c8x8i
m2ci 4m7c9x8i
9c9x9i i
i 9m9c9x8i
m i
i m
m9i i
9m8c7xi c2x8i

Output for the Sample Input

3x
x
6cx
5m9c9x9i
m
9m9c9x9i
mi
mi
mx
9m9c9x9i

Solution in JAVA (judge verdict: Accepted)


import java.io.*;
import java.util.*;

public class Main {
	FastScanner in = new FastScanner(System.in);
	PrintWriter out = new PrintWriter(System.out);
	
	int convert(String s) {
		int res = 0;
		int x = 1;
		for (int i = 0; i < s.length(); i++) {
			switch (s.charAt(i)) {
			case 'm':
				res += x * 1000;
				x = 1;
				break;
			case 'c':
				res += x * 100;
				x = 1;
				break;
			case 'x':
				res += x * 10;
				x = 1;
				break;
			case 'i':
				res += x;
				x = 1;
				break;
			default:
				x = s.charAt(i) - '0';
			}
		}
		
		return res;
	}

	String revConvert(int x) {
		String res = "";
		String TEMPLATE = "ixcm";
		
		for (int i = 0; i < 4; i++) {
			int val = x % 10;
			x /= 10;
			if (val == 0) continue;
			
			res = TEMPLATE.charAt(i) + res;
			if (val != 1) {
				res = val + res;
			} 
		}
		return res;
	}
	
	public void run() {
		int n = in.nextInt();
		for (int t = 0; t < n; t++) {
			String s1 = in.next(), s2 = in.next();
			
			int a = convert(s1), b = convert(s2);
			System.out.println(revConvert(a + b));
		}
		out.close();
	}

	public static void main(String[] args) {
		new Main().run();
	}

	public void mapDebug(int[][] a) {
		System.out.println("--------map display---------");

		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[i].length; j++) {
				System.out.printf("%3d ", a[i][j]);
			}
			System.out.println();
		}

		System.out.println("----------------------------");
		System.out.println();
	}

	public void debug(Object... obj) {
		System.out.println(Arrays.deepToString(obj));
	}

	class FastScanner {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FastScanner(InputStream stream) {
			this.stream = stream;
			//stream = new FileInputStream(new File("dec.in"));

		}

		int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		boolean isEndline(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		int[] nextIntArray(int n) {
			int[] array = new int[n];
			for (int i = 0; i < n; i++)
				array[i] = nextInt();

			return array;
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		long[] nextLongArray(int n) {
			long[] array = new long[n];
			for (int i = 0; i < n; i++)
				array[i] = nextLong();

			return array;
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		double[] nextDoubleArray(int n) {
			double[] array = new double[n];
			for (int i = 0; i < n; i++)
				array[i] = nextDouble();

			return array;
		}

		String next() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		String[] nextStringArray(int n) {
			String[] array = new String[n];
			for (int i = 0; i < n; i++)
				array[i] = next();

			return array;
		}

		String nextLine() {
			int c = read();
			while (isEndline(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}
	}
}