/* Topcoder SRM 699, D2, 500-pointer: LastDigit. * James S. Plank * Fri Nov 25 11:20:03 EST 2016 */ #include #include #include #include #include using namespace std; class LastDigit { public: long long findX(long long S); }; long long LastDigit::findX(long long S) { long long T; /* T is the biggest number <= S with all repeated digits. */ long long I; /* I is the first digit of T with all zeros. */ long long RV; /* This is the return value of the recursive call */ string SS; /* The string version of S. */ string ST; /* The string version of T. */ string SI; /* The string version of I. */ string SRV; /* The string version of RV. */ char buf[50]; /* This is to convert long long's to strings. */ int i; /* Base case. */ if (S < 10) return S; /* Create string version of S. */ sprintf(buf, "%lld", S); SS = buf; /* Create T from SS. If it's too big, the either subtract all 1's from it, or make it be all 9's, and one digit smaller. */ ST = buf; for (i = 1; i < ST.size(); i++) ST[i] = ST[0]; if (ST > SS) { if (ST[0] != '1') { for (i = 0; i < ST.size(); i++) ST[i]--; } else { for (i = 0; i < ST.size(); i++) ST[i] = '9'; ST.pop_back(); } } /* Now, create SI, and convert SI and ST back to I and T */ SI = ST; for (i = 1; i < SI.size(); i++) SI[i] = '0'; sscanf(ST.c_str(), "%lld", &T); sscanf(SI.c_str(), "%lld", &I); /* Make the recursive call, and check to make sure that the return value is not too big. */ RV = findX(S-T); if (RV != -1) { sprintf(buf, "%lld", RV); SRV = buf; if (SRV.size() == ST.size()) RV = -1; } /* If the return value is ok, then add I, and you're done. */ if (RV != -1) RV += I; return RV; }