可用回溯,剪枝也较容易。由于字符最长是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; }