PAT 自学题解 A1016【有测试点2,3,4的注释,仔细看代码哦】

 sort的用法

二维字符数组为空,一整行为空

二位字符数组赋值,一整行赋值

【代码是错的,以后改,如果有uu愿意帮忙的话,能不能看看是哪错了啊】

【现在已经改过来了,看第二个】

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1010


struct People
{
    char id[30]={0};
    int month=0,day=0,hour=0,minute=0;//月份
    char state[30]={0};
}people[N],temp[N];//people对应每一个输入的数据,temp对应整理好1个人的n次通话数据的数据,即中间变量,用于输出
int map[26]={0};//24个小时中每小时对应的通话费用
char id[N][30]={0};//多少种人
void minute(People a,int &t,double &money)//一次通话花费的时长,和金钱,a前,b后 初始时间是1:0:0
{
    if(a.day!=1)
    {
        t=(a.day-1)*24*60;
        for(int i=0;i<=24;i++)
            money+=map[i]*60;
    }
    if(a.hour!=0)
    {
        t+=a.hour*60;
        for(int i=0;i<a.hour;i++)
            money+=map[i]*60;
    }
    if(a.minute!=0)
    {
        t+=a.month;
        money+=map[a.hour]*a.minute;
    }

}
bool cmp(People a,People b)//按照时间给每个人的通话排一下序列
{
    if(a.month!=b.month) return a.month<b.month;
    if(b.day!=a.day)return a.day<b.day;
    if(a.hour!=b.hour) return a.hour<b.hour;
    return a.minute<b.minute;
}


int main()
{
    //存放24小时中每小时对应的通话费用
    for(int i=0;i<24;i++) cin>>map[i];


    int n=0;
    cin>>n;//总的通话数
    for(int i=0;i<n;i++)
    {
        scanf("%s %02d:%02d:%02d:%02d %s",people[i].id,&people[i].month,&people[i].day,&people[i].hour,&people[i].minute,people[i].state);
    }


    //筛选出一共有多少种人
    int k=1;
    strcpy(id[0],people[0].id);
    for(int i=0;i<n;i++)
    {
        int b=0;//标志 代表此人不在数组中
        int j=0;
        for( j=0;strlen(id[j])!=0;j++)//判定字符串数组为空NULL
        {
            if(strcmp(people[i].id,id[j])!=0) continue;//比较两个字符数组的是否相同
            else
            {
                b=1;
                break;
            }

        }
        if(b==0) {strcpy(id[j],people[i].id);k++;}//添加新的人员 字符数组赋值 strcpy
    }
    //将名字按照字典序排列
   // sort(&id[0],&id[k],cmp1);//sort的用法

    //输出每个人的开销
    for(int i=0;i<k;i++)
    {
        int k1=0;//中间变量,记录temp中存的数据
        for(int j=0;j<n;j++)
        {
            if(strcmp(id[i],people[j].id)==0) temp[k1++]=people[i];
        }
        sort(&temp[0],&temp[k1],cmp);//按照时间顺序给一个人的n次通话记录进行排序
        cout<<temp[0].id<<" "<<temp[0].month<<endl;
        double sum=0;//存放一个人n次通话的总开销
        //一个人第j次通话花费多少
        for(int j=0;j<k1;)
        {
            int t1=0,t2=0;
            double money1=0,money2=0;
            minute(temp[j],t1,money1);
            printf("%02d:%02d:%02d ",temp[j].day,temp[j].hour,temp[j].minute);
            j++;
            minute(temp[j],t2,money2);
            printf("%02d:%02d:%02d ",temp[j].day,temp[j].hour,temp[j].minute);
            j++;
            sum+=money2-money1;
            t1=t2-t1;
            printf("%d %lf\n",t1,sum*0.01);

        }
    }



}

以下是经过“略微”修改的代码,有测试点2,3,4的备注,这道题思路不难,就是代码有点多,有个大佬的代码不到60行,但介于我还没学map,所以没怎么看,附上大佬的链接59行代码​​​​​​​

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include <cstring>
using namespace std;
int map[26]={0};
struct ID
{
    char name[50]={0};
    int m=0,dd=0,hh=0,mm=0;//月,日,时,分
    char state[30]={0};

}id[1010],temp[1010],temp1[1010];//id是输入的,temp是中间变量
char name[1010][30]={0};//总共有多少个用户
bool cmp1(char a[30],char b[30])
{
    int l1=strlen(a);
    int l2=strlen(b);
    for(int i=0;i<l1||i<l2;i++)
    {
        if(a[i]==b[i]) continue;
        else return a[i]<b[i];
    }


}
bool cmp(ID a,ID b)//按照时间给每个人的通话排一下序列
{
    if(a.m!=b.m) return a.m<b.m;
    if(a.dd!=b.dd) return a.dd<b.dd;
    if(a.hh!=b.hh) return a.hh<b.hh;
    if(a.mm!=b.mm) return a.mm<b.mm;
}

int minute(ID a,int &time,double &money)//time 和money分别为从1:0:0开始计算得时间和金钱
{
    time=0;
    money=0;
    if(a.dd !=1)
    {
        time+=(a.dd-1)*24*60;
        for(int i=0;i<24;i++)
        {
            money+=map[i]*60;
        }
        money=(a.dd-1)*money;
    }
    if(a.hh!=0)
    {
        time+=a.hh*60;
        for(int i=0;i<a.hh;i++)
        {
            money+=map[i]*60;
        }
    }
    if(a.mm!=0)
    {
        time+=a.mm;
        money+=map[a.hh]*a.mm;
    }

}
int main()
{
    for(int i=0;i<24;i++) cin>>map[i];
   int n=0;//共有多少条记录
   cin>>n;
    for(int i=0;i<n;i++) scanf("%s %02d:%02d:%02d:%02d %s",&id[i].name,&id[i].m,&id[i].dd,&id[i].hh,&id[i].mm,&id[i].state);

    //寻找总共有多少个用户,存入name【】【】中
    int k=0;//记录用户的数量
    for (int i = 0; i < n; i++)
    {
        if (i == 0) strcpy(name[k++], id[i].name);//初始赋值名字
        //循环判断name【】中是否有id[i].name
        else
        {
            int b=0;//此人不在name【】中
            for(int j=0;j<k;j++)
            {
                if(strcmp(name[j],id[i].name)!=0) continue;//此人不在
                else b=1;//此人在
            }
            if(b==0) strcpy(name[k++], id[i].name);
        }
    }

    //将用户按照字典序列进行排序


    for(int i=0;i<k;i++)
    {
        for(int j=i+1;j<k;j++)
        {
            if(cmp1(name[i],name[j])) continue;
            else
            {
                char name1[30]={0};
                strcpy(name1,name[i]);
                strcpy(name[i],name[j]);
                strcpy(name[j],name1);

            }
        }

    }

    //输出每个人的开销
    for(int i=0;i<k;i++)
    {
        int k1=0;//中间变量,记录temp中存的数据
        for(int j=0;j<n;j++)
        {
            if(strcmp(name[i],id[j].name)==0) temp[k1++]=id[j];
        }
        //将通话记录按照发生的先后顺序排序
        sort(&temp[0],&temp[k1],cmp);//按照时间顺序给第i个人的k1次通话记录进行排序

        //进行 on-off的匹配
        int k2=0;//k2指的是最终的通话记录,保证是偶数个

        for(int j=0;j<k1-1;j++)//
        {
            if (strcmp(temp[j].state, "on-line") == 0&&strcmp(temp[j+1].state, "off-line") == 0)//对应测试点4 之前比较两个状态不同就进行输出是不可以的哦
            {
                temp1[k2++] = temp[j];
                temp1[k2++] = temp[j+1];
                j++;
            }
        }
        double total=0;
        if(k2!=0)printf("%s %02d\n",temp1[0].name,temp1[0].m);
        else continue;//对应测试点 2,3  如果on-off没有匹配成功则跳过该用户
        for(int j=0;j<k2;j++)
        {
            int time1=0,time2=0;
            double money1=0,money2=0;
            minute(temp1[j],time1,money1);
            printf("%02d:%02d:%02d ",temp1[j].dd,temp1[j].hh,temp1[j].mm);
            j++;
            minute(temp1[j],time2,money2);
            printf("%02d:%02d:%02d ",temp1[j].dd,temp1[j].hh,temp1[j].mm);
            printf("%d $%.2lf\n",time2-time1,(money2-money1)*0.01);
            total+=money2-money1;

        }
        printf("Total amount: $%.2lf\n",total*0.01);




    }
}

 

太开心了,这道题折磨了我好几天呜呜,所以凑不要脸的我附上AC的截图,偶吼吼吼吼 

【其实主要还是自己懒,好几次点开clion都不能调试,有时候出现这种问题重启就好了,今天特别生气,两次重启还是不能调试,默默点开vs发现可以,于是乎,我不干了,推翻重来,重写了一遍代码,所以第二段代码跟第一段在参数上的形式有些许不同,但都差不多】

​​​​​​​

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值