int get_lucky_price(int price, const vector & number) 题意大概是给你一个数price,比如1000,然后有unlucky_num,有{1,4,7,5},要求price里面不能出现unlucky,又不能出现0,也就是unlucky至少包括0,别忘记了这个。求满足要求的大于等于price的最小值,所有的数字都是lucky的。上面的答案是2222。不知道我理解的题意对不对。
看到这道题,我感觉这道题挺相似Numeric Keypad,有时间可以做一下。
直接想法就是从高位到低位,然后找不满足要求的,然后往上增加,比如1000,第一个数是1,不满足,第一个比1大的满足要求的为2,然后这位变为2,这时候,后面的数都不需要考虑了,直接设置为lucky里面的最小值即可。因为要满足尽可能的小,后面的只需要保持lucky,然后最小即可。
这里面有一个trick,找到第一个,不满足要求的,可能需要进位,假如unluck为{8,9},price为2779,然后第一个不满足要求为第四位上的9,然后进位,发现进位后7变为8,8也是不满足要求的,这个时候就需要找到最左边的进位满足要求的,有时候甚至需要在开始的位置补一个数字,然后剩下的数字设置为最小的符合要求的即可。
大概思想就是这样,昨天看到这题,想到上面那道,但是没仔细分析,其实套路一样,还有昨天时间实在紧张,没有做出来。
有时间补一下代码。
int get_lucky_price(int price, const vector<int> & number) {
vector<bool> tag(10, 0);
tag[0] = 1;
for (int i = 0; i < number.size(); i++) {
tag[number[i]] = 1;
}
int mi = -1,ma = -1;
for (int i = 0; i < 10; i++) {
if(tag[i]) continue;
if(mi == -1) {
mi = ma = i;
} else {
ma = i;
}
}
//cout << mi << " " << ma << endl;
stringstream ss; ss << price;
string s = ss.str();
bool flag = 0;
for (int i = 0; i < s.size(); i++) {
int cur = s[i] - '0';
if(!tag[cur]) continue;
if(cur > ma) {
int k = i - 1;
while(k >= 0 && s[k] - '0' == ma) k--;
if(k < 0) {
string t(s.size() + 1, '0' + mi);
s = t;
} else {
//cout << "asd" << endl;
for (int j = s[k] - '0' + 1; j < 10; j++) {
if(!tag[j]) {
s[k] = '0' + j;
break;
}
}
string t = s.substr(0, k + 1);
t.append(s.size() - k - 1, '0' + mi);
s = t;
break;
}
} else {
for (int j = cur + 1; j < 10; j++) {
if(!tag[j]) {
s[i] = '0' + j;
break;
}
}
string t = s.substr(0, i + 1);
t.append(s.size() - i - 1, '0' + mi);
s = t;
break;
}
}
stringstream s1; s1 << s;
int res; s1 >> res;
return res;
}
void solve() {
vector<int> v;v.pb(1);v.pb(4);v.pb(8);v.pb(9);
cout << get_lucky_price(388, v) << endl;
}