private _ANSWER solve(string s, string t) { var ans = new Triplet <long, long, long>(long.MaxValue, long.MaxValue, long.MaxValue); //0: s>t //1: s=t //1: t<s var dp = Enumerate(3, x => new Triplet <long, long, long>(long.MaxValue, 0, 0)); dp[1].I = 0; for (int i = 0; i < s.Length; i++) { var next = Enumerate(3, x => new Triplet <long, long, long>(long.MaxValue, 0, 0)); for (int u = 0; u < 10; u++) { if (s[i] != u + '0' && s[i] != '?') { continue; } for (int v = 0; v < 10; v++) { if (t[i] != v + '0' && t[i] != '?') { continue; } if (u < v) { for (int k = 0; k < 3; k++) { long d; int to; Triplet <long, long, long> neq; if (k == 0) { if (dp[k].I == long.MaxValue) { continue; } d = dp[k].I * 10 - Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 0; } else if (k == 1) { if (dp[k].I == long.MaxValue) { continue; } d = Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 2; } else { if (dp[k].I == long.MaxValue) { continue; } d = dp[k].I * 10 + Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 2; } next[to] = Triplet.Min(next[to], neq); } } else if (u == v) { for (int k = 0; k < 3; k++) { long d; int to; Triplet <long, long, long> neq; if (k == 0) { if (dp[k].I == long.MaxValue) { continue; } d = dp[k].I * 10 - Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 0; } else if (k == 1) { if (dp[k].I == long.MaxValue) { continue; } d = Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 1; } else { if (dp[k].I == long.MaxValue) { continue; } d = dp[k].I * 10 + Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 2; } next[to] = Triplet.Min(next[to], neq); } } else { for (int k = 0; k < 3; k++) { long d; int to; Triplet <long, long, long> neq; if (k == 0) { if (dp[k].I == long.MaxValue) { continue; } d = dp[k].I * 10 + Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 0; } else if (k == 1) { if (dp[k].I == long.MaxValue) { continue; } d = Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 0; } else { if (dp[k].I == long.MaxValue) { continue; } d = dp[k].I * 10 - Math.Abs(v - u); neq = new Triplet <long, long, long>(d, dp[k].J * 10 + u, dp[k].K * 10 + v); to = 2; } next[to] = Triplet.Min(next[to], neq); } } } } dp = next; } for (int i = 0; i < 3; i++) { ans = Triplet.Min(ans, dp[i]); } var a = new List <long>(); var b = new List <long>(); for (int i = 0; i < s.Length; i++) { a.Add(ans.J % 10); b.Add(ans.K % 10); ans.J /= 10; ans.K /= 10; } a.Reverse(); b.Reverse(); return(new _ANSWER(ans.I, a.AsJoinedString(""), b.AsJoinedString(""))); }