[COCI2018-2019#5] Titlovi 题解

· · 题解

题目

思路

先读入编号(整型),接着读入时间(字符串),然后读入字幕内容。

读入字幕时遇到空行就停止(这组数据读完了,要读下一组数据了),

遇到井号停止读入。最后读入 T

输出时边输出,边把时间调整就行了。

坑点

代码

函数

1. check 函数

作用:判断是字幕还是下一个数据(这里我借鉴了 @shangyuang 的题解写的读入方式)。

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

2. zh 函数

作用:把时间进行调整,同时转化进率。

void zh(int f[10]){  
    f[1]+=t; //先加毫秒 ,因为 T 的单位是毫秒 
    if(t>=0){  //要将字幕向后调 
    //下面每条语句都差不多,就是超出进率,多的给前一位,剩下的给这一位 
        if(f[1]>=1000) f[2]+=f[1]/1000,f[1]%=1000;
        if(f[2]>=60) f[3]+=f[2]/60,f[2]%=60;
        if(f[3]>=60) f[4]+=f[3]/60,f[3]%=60;
    }else{//要将字幕向前调
        int sum=0;
        if(f[1]<0){
            //注意绝对值!!! 
            sum=abs(f[1])/1000; //要补的
            //有余数再加一个单位,当前位为进率减余数 
            if(abs(f[1])%1000!=0) sum++,f[1]=1000-abs(f[1])%1000;
            else f[1]=0;// 刚好补完,变零 
            f[2]-=sum; //前一位减相应的单位 
        } 
        if(f[2]<0){//同上 
            sum=abs(f[2])/60;
            if(abs(f[2])%60!=0) sum++,f[2]=60-abs(f[2])%60;
            else f[2]=0;
            f[3]-=sum;
        }
        if(f[3]<0){//同上
            sum=abs(f[3])/60;
            if(abs(f[3])%60!=0) sum++,f[3]=60-abs(f[3])%60;
            else f[3]=0;
            f[4]-=sum;
        }
    }
}

3. pd 函数

作用:从时间(字符串类型)中分离出小时、分钟、秒和毫秒,并根

T 进行时间调整,最后将编号、调整好的时间、字幕内容输出。

void pd(int k){ 
    string st=a[k].time+':'; //在最后加一个 ':',防止最后一个时间没有分离出来 
    int sum1=0,x=4,y=4,f1[10]={0},f2[10]={0};//f1 表示开始时间,f2 表示结束时间 
    //下面我是倒序存的,当然正序存也可以 
    for(int i=0;i<st.size();i++){
        if(i==13) i=17; //略过中间 " --> " 部分 
        if(st[i]==':'||st[i]==','||st[i]==' '){ //遇到这几个符号说明已经有一个时间分离出来了 
            if(x>0) f1[x]=sum1,x--;//如果 x 不为零,说明开始时间还没读完,放进 f1 数组 
            else f2[y]=sum1,y--;//否则放入 f2 数组 
            sum1=0; //归零 
        }else sum1=sum1*10+(st[i]-48); //字符串转数字 
    } 
    zh(f1);//开始时间调整 
    zh(f2);//结束时间调整
    //输出 
    printf("%d\n",a[k].num);
    printf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",f1[4],f1[3],f1[2],f1[1],f2[4],f2[3],f2[2],f2[1]);  
    printf("%s\n",a[k].book.c_str());
    if(k<n) printf("\n");
    else printf("#");    
}

主函数

#include<bits/stdc++.h>
#include<string>
using namespace std;
int n,t;
string sta,stb; //sta 表示开始时间,stb 表示结束时间 
struct node{
    int num; //编号 
    string time;//时间 
    string book;//字幕 
};
node a[1010];
//这里是函数部分(略)
int main(){
    while(1){ 
        n++;
        scanf("%d",&a[n].num);//读入编号(一定要用 scanf!!!) 
        sta.resize(12);//分配空间 
        stb.resize(12);//分配空间
        scanf("%s --> %s\n",&sta[0],&stb[0]);//读入时间 
        a[n].time=sta+" --> "+stb;//加到 time 里 
        while(1){ //读入字幕内容 
            getline(cin,sta);
            //如果是 '#'(读完了)或不是字幕(要读下一组数据)跳出 
            if(sta[0]=='#'||check(sta[0])==0) break;
            //字幕加到 book 里 
            if(a[n].book.empty()) a[n].book+=sta;
            else a[n].book+='\n'+sta; 
        }  
        if(sta[0]=='#') break;//是'#'(读完了)跳出 
    }
    cin>>t; //输入要调整的时间 
    for(int i=1;i<=n;i++) pd(i);//时间调整 
    return 0;
}

AC 代码

#include<bits/stdc++.h>
#include<string>
using namespace std;
int n,t;
string sta,stb;  
struct node{
    int num;  
    string time;
    string book; 
};
node a[1010];
void zh(int f[10]){  
    f[1]+=t; 
    if(t>=0){   

        if(f[1]>=1000) f[2]+=f[1]/1000,f[1]%=1000;
        if(f[2]>=60) f[3]+=f[2]/60,f[2]%=60;
        if(f[3]>=60) f[4]+=f[3]/60,f[3]%=60;
    }else{
        int sum=0;
        if(f[1]<0){ 
            sum=abs(f[1])/1000; 
            if(abs(f[1])%1000!=0) sum++,f[1]=1000-abs(f[1])%1000;
            else f[1]=0;
            f[2]-=sum;  
        } 
        if(f[2]<0){ 
            sum=abs(f[2])/60;
            if(abs(f[2])%60!=0) sum++,f[2]=60-abs(f[2])%60;
            else f[2]=0;
            f[3]-=sum;
        }
        if(f[3]<0){
            sum=abs(f[3])/60;
            if(abs(f[3])%60!=0) sum++,f[3]=60-abs(f[3])%60;
            else f[3]=0;
            f[4]-=sum;
        }
    }
}
void pd(int k){ 
    string st=a[k].time+':'; 
    int sum1=0,x=4,y=4,f1[10]={0},f2[10]={0};
    for(int i=0;i<st.size();i++){
        if(i==13) i=17; 
        if(st[i]==':'||st[i]==','||st[i]==' '){  
            if(x>0) f1[x]=sum1,x--;
            else f2[y]=sum1,y--; 
            sum1=0; 
        }else sum1=sum1*10+(st[i]-48); 
    } 
    zh(f1); 
    zh(f2);
    printf("%d\n",a[k].num);
    printf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",f1[4],f1[3],f1[2],f1[1],f2[4],f2[3],f2[2],f2[1]);  
    printf("%s\n",a[k].book.c_str());
    if(k<n) printf("\n");
    else printf("#");    
}
bool check(char c){
    return (c>='a'&&c<='z'||c>='A'&&c<='Z'||c==' '||c==','||c=='?'||c=='!'||c=='.');
}
int main(){
    while(1){ 
        n++;
        scanf("%d",&a[n].num);
        sta.resize(12); 
        stb.resize(12);
        scanf("%s --> %s\n",&sta[0],&stb[0]); 
        a[n].time=sta+" --> "+stb; 
        while(1){ 
            getline(cin,sta);
            if(sta[0]=='#'||check(sta[0])==0) break;
            if(a[n].book.empty()) a[n].book+=sta;
            else a[n].book+='\n'+sta; 
        }  
        if(sta[0]=='#') break;
    }
    cin>>t; 
    for(int i=1;i<=n;i++) pd(i);
    return 0;
}

其他