可用回溯,剪枝也较容易。由于字符最长是5,所以递归深度较小,数据范围小时和分钟分别是24,60上限,再加上第一个时间必须小于第二个时间,可以剪掉大量无用分枝。最后计算出来的差值分别和要求的极值进行比较,不断更新即可。
#include <cctype>
#include <climits>
#include <iostream>
using namespace std;
int big = 0;
int small = INT_MAX;
int tab[5]={3, 10, 0, 6, 10};
void getMinMax(string& s, string&t, int i) {
auto loop_cnt = tab[i];
if (i==2) {
int a = 10*(s[0]-'0')+s[1]-'0';
int b = 10*(t[0]-'0')+t[1]-'0';
if (a>b || a>23 || b>23) return;
//cout << a<< " - " << b << endl;
}
else if (i==5) {
int a = 10*(s[0]-'0')+s[1]-'0';
int b = 10*(t[0]-'0')+t[1]-'0';
int c = 10*(s[3]-'0')+s[4]-'0';
int d = 10*(t[3]-'0')+t[4]-'0';
if (c>59 || d>59) return;
if (a==b && c>=d) return;
int cur = (b-a)*60 + d-c;
if (cur>big) big = cur;
if (cur < small) small = cur;
//cout <<a<<"-"<<c<<" "<<b<<"-"<<d<<endl;
return;
}
if (s[i]=='?') {
for (auto j=0; j<loop_cnt; j++) {
auto a = s[i];
s[i] = '0' + j;
if (!isdigit(t[i])) {
for (auto j=0; j<loop_cnt; j++) {
auto b=t[i];
t[i] = '0' + j;
getMinMax(s, t, i+1);
t[i] = b;
}
}
else {
getMinMax(s, t, i+1);
}
s[i] = a;
}
}
else if (s[i]==':') {
getMinMax(s, t,i+1);
}
else if (isdigit(s[i])) {
if (isdigit(t[i])) {
getMinMax(s, t, i+1);
}
else {
for (auto j=0; j<loop_cnt; j++) {
auto tmp = t[i];
t[i] = '0' + j;
getMinMax(s, t, i+1);
t[i] = tmp;
}
}
}
}
int main() {
string s,t;
cin >> s >> t;
getMinMax(s, t, 0);
cout << small << " " << big << endl;
}

京公网安备 11010502036488号