P7374题解

· · 题解

原题目传送门

题意

此题题意较好理解,给出 字幕序号开始结束时间字幕内容。将其前/后移,再进行输出。

解题步骤

  1. 将字幕数据(序号、时间、内容)读入结构体。

  2. 读入 T ,将时间加 T

  3. 处理进位/退位。

  4. 按格式输出。

详解

读入

我们可以创造一个结构体,将每一部分的字母信息储存在里面。因为字幕有的不止 1 行,所以我们用字符串的数组,分行储存。

于是,代码如下:

struct ZM {
    int number;
    int h1,m1,s1,t1;//start time
    int h2,m2,s2,t2;//end time
    string zm[51];
    int zm_len;
} a[31];

读入比较麻烦,为了确认这是字幕而不是下一组的数据 (我因为这个调了 5 小时),我们使用一个判断函数,因为:

每一段字幕之间用一个空行隔开。字幕内容包含英文字母、空格和字符 ,.?!. 等。

bool pd(char a) {
    return a>='a'&&a<='z'||a>='A'&&a<='Z'||a==' '||a==','||a=='?'||a=='!'||a=='.';
}

有了这两个“神器”,咱就开始读入:

int n=0;
    for(;;) {
        cin>>a[i].number;//读入序号
        scanf("%d:%d:%d,%d --> %d:%d:%d,%d\n",&a[i].h1,&a[i].m1,&a[i].s1,&a[i].t1,&a[i].h2,&a[i].m2,&a[i].s2,&a[i].t2);//读入时间
        n++;
        string s="";
        bool flag=1;
        while(1) {
            getline(cin,s);

            if(s[0]=='#') {
                flag=0;
                break;//读到#就跳出
            }
            if(pd(s[0])) {
                a[i].zm[++a[i].zm_len]=s;
            } else break;//进行下一组读入
        }
        if(flag==0) break;

    }
    cin>>t;

处理

这里容易忽略的一个点,就是多次进位与退位。其做法类似于高精度加/减法。

函数:

void cl(int i) {
    while(a[i].t1<0) {
        a[i].s1--;
        a[i].t1+=1000;
    }
    while(a[i].t2<0) {
        a[i].s2--;
        a[i].t2+=1000;
    }
    while(a[i].s1<0) {
        a[i].m1--;
        a[i].s1+=60;
    }
    while(a[i].s2<0) {
        a[i].m2--;
        a[i].s2+=60;
    }
    while(a[i].m1<0) {
        a[i].h1--;
        a[i].m1+=60;
    }
    while(a[i].m2<0) {
        a[i].h2--;
        a[i].m2+=60;
    }
    a[i].s1+=a[i].t1/1000;
    a[i].t1%=1000;
    a[i].s2+=a[i].t2/1000;
    a[i].t2%=1000;

    a[i].m1+=a[i].s1/60;
    a[i].s1%=60;
    a[i].m2+=a[i].s2/60;
    a[i].s2%=60;

    a[i].h1+=a[i].m1/60;
    a[i].m1%=60;
    a[i].h2+=a[i].m2/60;
    a[i].m2%=60;
}

main() 中的处理:

for(int i=1; i<=n; i++) {
    a[i].t1+=t;
    a[i].t2+=t;
    cl(i);
}

输出

输出就比较简单了:

for(int i=1; i<=n; i++) {
    printf("%d\n",a[i].number);
    printf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",a[i].h1,a[i].m1,a[i].s1,a[i].t1,a[i].h2,a[i].m2,a[i].s2,a[i].t2);
    for(int j=1; j<=a[i].zm_len; j++)
        cout<<a[i].zm[j]<<"\n";
    if(i!=n) {
        printf("\n");
    }

}
cout<<"#";

附上 AC 代码:

#include<bits/stdc++.h>
using namespace std;

int t;
struct ZM {
    int number;
    int h1,m1,s1,t1;//start time
    int h2,m2,s2,t2;//end time
    string zm[51];
    int zm_len;
} a[31]; //开100绝对够了,可是不习惯

void cl(int i) {
    while(a[i].t1<0) {
        a[i].s1--;
        a[i].t1+=1000;
    }
    while(a[i].t2<0) {
        a[i].s2--;
        a[i].t2+=1000;
    }
    while(a[i].s1<0) {
        a[i].m1--;
        a[i].s1+=60;
    }
    while(a[i].s2<0) {
        a[i].m2--;
        a[i].s2+=60;
    }
    while(a[i].m1<0) {
        a[i].h1--;
        a[i].m1+=60;
    }
    while(a[i].m2<0) {
        a[i].h2--;
        a[i].m2+=60;
    }
    a[i].s1+=a[i].t1/1000;
    a[i].t1%=1000;
    a[i].s2+=a[i].t2/1000;
    a[i].t2%=1000;

    a[i].m1+=a[i].s1/60;
    a[i].s1%=60;
    a[i].m2+=a[i].s2/60;
    a[i].s2%=60;

    a[i].h1+=a[i].m1/60;
    a[i].m1%=60;
    a[i].h2+=a[i].m2/60;
    a[i].m2%=60;
}
bool pd(char a) {
    return a>='a'&&a<='z'||a>='A'&&a<='Z'||a==' '||a==','||a=='?'||a=='!'||a=='.';
}
int main() {
    int n=0,i=1;
    for(;;) {
        cin>>a[i].number;
        scanf("%d:%d:%d,%d --> %d:%d:%d,%d\n",&a[i].h1,&a[i].m1,&a[i].s1,&a[i].t1,&a[i].h2,&a[i].m2,&a[i].s2,&a[i].t2);
        n++;
        string s="";
        bool flag=1;
        while(1) {
            getline(cin,s);

            if(s[0]=='#') {
                flag=0;
                break;
            }
            if(pd(s[0])) {
                a[i].zm[++a[i].zm_len]=s;
            } else break;
        }
        if(flag==0) break;
        i++;
    }
    cin>>t;

    for(int i=1; i<=n; i++) {
        a[i].t1+=t;
        a[i].t2+=t;
        cl(i);
    }
    for(int i=1; i<=n; i++) {
        printf("%d\n",a[i].number);
        printf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",a[i].h1,a[i].m1,a[i].s1,a[i].t1,a[i].h2,a[i].m2,a[i].s2,a[i].t2);
        for(int j=1; j<=a[i].zm_len; j++)
            cout<<a[i].zm[j]<<"\n";
        if(i!=n) {
            printf("\n");
        }

    }
    cout<<"#";
    return 0;
}

最后,感谢 @sz_wangshengyi @zct_sky 帮助我写这篇题解!