[COCI2018-2019#5] Titlovi 题解
题目
思路
先读入编号(整型),接着读入时间(字符串),然后读入字幕内容。
读入字幕时遇到空行就停止(这组数据读完了,要读下一组数据了),
遇到井号停止读入。最后读入
输出时边输出,边把时间调整就行了。
坑点
-
输入时要用
scanf,不然 时间超限。 -
输入时注意
\n,\r,不然你就会莫名其妙地运行错误或答案错误。
代码
函数
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 函数
作用:从时间(字符串类型)中分离出小时、分钟、秒和毫秒,并根
据
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;
}
其他
-
本人刚开始写题解,如有错误欢迎指出。
-
特别感谢 @Jerrlee✅ 帮我改了一些代码上的问题。
-
看在我码了这么多字和寄了这么多次的份上,点个赞吧!
-
祝愿看了这篇题解的人本题 AC!