(追記)editorial読んだら、queueでいいっぽい。最初に埋まったやつがbestになるから、確かにqueueでOK。
typedef pair<int, pair<string, int> > ISI;
string dp[10000];
class MultiplesWithLimit {
string format(string x) {
if (x.length() < 9)
return x;
char ret[512];
sprintf(ret, "%s...%s(%d digits)", x.substr(0, 3).c_str(), x.substr(x.length()-3).c_str(), x.length());
return ret;
}
bool contain(vector<int> vec, int n) {
REP(i, vec.size())
if (vec[i] == n)
return true;
return false;
}
public:
string minMultiples(int N, vector<int> forbiddenDigits) {
vector<int> nums;
REP(i, 10) {
if (!contain(forbiddenDigits, i))
nums.push_back(i);
}
priority_queue<ISI, vector<ISI>, greater<ISI> > Q;
Q.push(MP(0, MP("", 0)));
string ret = "";
REP(i, 10000) dp[i] = "";
while (!Q.empty()) {
string str = Q.top().second.first;
int rm = Q.top().second.second;
Q.pop();
if (rm == 0 && str != "") {
ret = str;
break;
}
if (dp[rm].length() < str.length() ||
(dp[rm].length() == str.length() && dp[rm] < str))
continue;
REP(i, nums.size()) {
int rm_t = (10 * rm + nums[i]) % N;
string str_t = str + (char)(nums[i] + '0');
if (str_t == "0") continue;
if (dp[rm_t] == "" ||
str_t.length() < dp[rm_t].length() ||
(str_t.length() == dp[rm_t].length() && str_t < dp[rm_t])
) {
dp[rm_t] = str_t;
Q.push(MP(str_t.length(), MP(str_t, rm_t)));
}
}
}
if (ret == "")
return "IMPOSSIBLE";
return format(ret);
}
};
0 件のコメント:
コメントを投稿