首页 > 其他分享 >PTA 1016 phone bills(把复杂的信息进行打包分类,把对象挑出来单个击破就容易解决的啦。

PTA 1016 phone bills(把复杂的信息进行打包分类,把对象挑出来单个击破就容易解决的啦。

时间:2023-02-04 22:23:05浏览次数:51  
标签:struct int PTA name phone time tollTime 1016 tmpR

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct record{
    char name[25],time[15],flag[10];
    int tollTime,onOff;
};
struct customers{
    int start,end;
};
int cmp(const void *a,const void *b){
    struct record *w=(struct record *)a;
    struct record *q=(struct record *)b;
    if(strcmp(w->name,q->name)!=0){
        return strcmp(w->name,q->name);
    }
    else return w->tollTime - q->tollTime;
}
int main(){
    int pay[24],i,k;
    for(i=0;i<24;i++){
        scanf("%d",&pay[i]); 
    }
    int n;
    scanf("%d",&n);
    struct record r[n];
    int tD,tH,tM;
    for(i=0;i<n;i++){
        scanf("%s %s %s",r[i].name,r[i].time,r[i].flag);
        tD=(r[i].time[3]-'0')*10+r[i].time[4]-'0';
        tH=(r[i].time[6]-'0')*10+r[i].time[7]-'0';
        tM=(r[i].time[9]-'0')*10+r[i].time[10]-'0';
        r[i].tollTime=tD*24*60+tH*60+tM;
        if(r[i].flag[1]=='f'){
            r[i].onOff=0;
        }
        else r[i].onOff=1;
    }
    qsort(r,n,sizeof(r[0]),cmp);
    struct customers c[n];
    int cSize=0;
    c[cSize].start=0;
    for(i=1;i<n;i++){
        if(strcmp(r[i].name,r[i-1].name)!=0){
            c[cSize++].end=i-1;
            c[cSize].start=i;
        }
    }
    c[cSize].end=n-1;
    int j;
    //printf("%d",cSize);
    for(i=0;i<=cSize;i++){
        int s=c[i].start,e=c[i].end;
        int isValid=0,haveOn=0,firstTmpIn=0,nextTmpR=0,isFirstN=1;
        struct record tmpR;
        double allPayment=0.0;
        for(j=s;j<=e;j++){
            if(r[j].onOff==1 && firstTmpIn==0){
                tmpR=r[j];
                firstTmpIn=1;
                haveOn=1;
            }
            if(r[j].tollTime>tmpR.tollTime && r[j].onOff==1){
                tmpR=r[j];
                haveOn=1;
            }
            if(r[j].tollTime>tmpR.tollTime && r[j].onOff==0){
                if(haveOn==1){
                    isValid=1;
//
                    int payTime=r[j].tollTime-tmpR.tollTime;
                    int startH,startM;
                    char tmpHc[5],tmpMc[5];
                    tmpHc[0]=tmpR.time[6];
                    tmpHc[1]=tmpR.time[7];
                    tmpHc[2]='\0';
                    tmpMc[0]=tmpR.time[9];
                    tmpMc[1]=tmpR.time[10];
                    tmpMc[2]='\0';
                    sscanf(tmpHc,"%d",&startH);
                    sscanf(tmpMc,"%d",&startM);
                    double yes60=0.0,payment=0.0;
                    if(startM+payTime<=60){
                        payment=payTime*pay[startH]/100.0;
                        yes60+=payment;
                    }
                    else{
                        int a=payTime-(60-startM);
                        int b=a/60,c=a%60;
                        for(k=0;k<b;k++){
                            yes60+=pay[(startH+k+1)%24]*60/100.0;    
                        }
                        yes60+=c*pay[(startH+k+1)%24]/100.0;
                        yes60+=(60-startM)*pay[startH]/100.0;
                        payment=yes60;
                    }
                    char *p1=tmpR.time+3,*p2=r[j].time+3;
                    if(isFirstN==1){
                        printf("%s %.2s\n",tmpR.name,tmpR.time);
                        isFirstN=0;
                    }
                    printf("%s %s %d $%.2f\n",p1,p2,payTime,payment);
                    allPayment+=payment;
//                    
                }
                haveOn=0;
                nextTmpR=1;
            }
            if(nextTmpR==1 && r[j].onOff==1){
                tmpR=r[j];
                nextTmpR=0;
                haveOn=1;
            }
            if(isValid==1 && j==e){
                printf("Total amount: $%.2f\n",allPayment);
            }
        }
    }
}

这道题的输入和后面的处理很复杂。

我的习惯是,如果Input Sample中的信息可以打包,也就是说存在一个小的对象,我就会搞一个结构体数组,把信息先简单分到小对象里。

看题目,输入name,time和onOrOff,输出要求字典序,一对通讯时间记录必须有效才能输出,而且要求是时间轴上紧邻的一对on和off,这里就复杂起来了。我们先处理字典序的问题,可以用qsort结构体排序的方式来获得正确的字典序。既然有效才能输出,那我们就来找一找有没有有效的一对通讯记录,怎么找馁?如果我们来找on后面的off,那是无法确定是否为同一用户的,因为我们将所有的记录都放在了数组上。而且参考面向对象编程的思维,我们应该想到要先将顾客分出来,再对每一个对象,也就是顾客进行处理。

最后做完之后发现这道题有很多信息,但是要抽丝剥茧地做,把信息细心分类,打包,也就很简单的拉~~~

标签:struct,int,PTA,name,phone,time,tollTime,1016,tmpR
From: https://www.cnblogs.com/lxj2001/p/17092532.html

相关文章