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