• 浙大PAT考试1013~1016(最伤的一次。。)



    我能说我1016WA了几天都不得最后还是拿别人代码交的么。

    。。

    真心找不到那个神数据。。


    自己把整个程序的流程都画出来了。细致推敲是木有问题的啊。。。


    题目地址:点击打开链接


    先从1013開始介绍。

    题目大意:给你n个城市,m条路,k个询问。每次询问。是假设没有城市q1,,,qk其它城市链接在一起至少须要多少条路。

    简单的并查集问题。对节点qi无论,其它的点用并查集。我们所要求的就是有多少个分量。ans个分量则须要ans-1条路就可以。详见代码:

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int maxn=1005;
    
    struct node
    {
        int x;
        int y;
    }nod[maxn*maxn];
    
    int fa[maxn];
    
    void init()
    {
        for(int i=1;i<=1000;i++)
            fa[i]=i;
    }
    
    int find1(int p)
    {
        if(fa[p]!=p) fa[p]=find1(fa[p]);
        return fa[p];
    }
    
    void merge1(int p,int q)
    {
        p=find1(p);
        q=find1(q);
        if(p!=q)
            fa[p]=q;
    }
    
    int main()
    {
        int n,m,k;
        int i;
        while(cin>>n>>m>>k)
        {
            for(i=0;i<m;i++)
                scanf("%d%d",&nod[i].x,&nod[i].y);
    
            int cur;
            while(k--)
            {
                scanf("%d",&cur);
                int res=0;
    
                init();
                for(i=0;i<m;i++)
                {
                    int p,q;
                    p=nod[i].x,q=nod[i].y;
                    if(p==cur||q==cur) continue;
                    merge1(p,q);
                }
                for(i=1;i<=n;i++)
                {
                    if(i==cur) continue;
                    if(fa[i]==i) res++;
                }
    
                printf("%d
    ",res-1);
            }
        }
        return 0;
    }
    
    /*
    3 2 3
    1 2
    1 3
    1 2 3
    */
    

    1014:

    题目大意:题目有点麻烦,意思是在取钱之类的背景下。。

    有n个窗体,每一个窗体黄线里面最多容下的人数m。k个客户。q个查询。

    然后依次给出你k个客户的在柜台的处理时间,然后q个查询,每次查询编号为qi的客户处理完之后的时间。时间是08:00開始,17:00结束。

    注意,这里有个bug。17:00结束是假设你在17:00之前还在柜台前面,就会被处理。

    解题思路:最開始我们先把队伍一个一个排好,由于题目说的意思是每次都会排在最少人数的队列中,假设队列人数有一样的。选编号小的。那么我们最開始处理的时候就先把n*m容量之类的排好,一个一个按着队列排。然后出一个进一个,依次模拟,详见代码:

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    using namespace std;
    
    int n,m,k,peo,ccnt;
    
    struct node
    {
        int t;
        int index;
    } nod[1005];
    
    queue <node> mq[25];
    int res[1005];
    int mp[25];
    
    void debug()
    {
        for(int i=1; i<=2; i++)
        {
            node x=mq[i].front();
            cout<<x.t<<" ";
            mq[i].pop();
            x=mq[i].front();
            cout<<x.t<<endl;
        }
    }
    
    void init()   //初始化,先预先站队
    {
        int i,j;
        for(int i=1;i<=1000;i++)
            res[i]=10000;
        for(i=1; i<=20; i++)
        {
            while(!mq[i].empty())
                mq[i].pop();
        }
    
        int cnt=0;
        for(i=1; i<=k; i+=n)
        {
            for(j=0; j<n; j++)
            {
                if(cnt==n*m)
                {
                    //debug();
                    peo=cnt+1;
                    return;
                }
                mq[j+1].push(nod[i+j]);
                cnt++;
            }
        }
    
        peo=cnt+1;   //peo代表下一个排队人的编号
        return;
    }
    
    void resolve()  //时间到了16:59,仅仅有reserved的人才干够完毕交易
    {
        int i;
        for(i=1; i<=n; i++)
        {
            if(!mq[i].empty())
            {
                node x=mq[i].front();
                res[x.index]=ccnt+mp[i];
            }
        }
        return;
    }
    
    void solve()
    {
        ccnt=1;
    
        for(int i=1; i<=n; i++)
        {
            if(!mq[i].empty())
            {
                node x=mq[i].front();
                mp[i]=x.t;
            }
        }
    
        while(1)
        {
            if(ccnt==540)
            {
                ccnt--;
                resolve();  //时间已到。仅仅处理在队首的
                break;
            }
    
            for(int i=1; i<=n; i++)
            {
                if(!mq[i].empty())
                {
                    mp[i]--;
                    if(mp[i]==0) //假设某个队伍有人完毕交易,立刻填充人进来
                    {
                        node x=mq[i].front();
                        mq[i].pop();
                        res[x.index]=ccnt;
                        if(peo<=k)
                            mq[i].push(nod[peo++]);
                        if(!mq[i].empty())
                        {
                            node x=mq[i].front();
                            mp[i]=x.t;
                        }
                    }
                }
            }
            ccnt++;
        }
    }
    
    int main()
    {
        int q,i;
        while(cin>>n>>m>>k>>q)
        {
            for(i=1; i<=k; i++)
            {
                cin>>nod[i].t;
                nod[i].index=i;
            }
            init();
            solve();
    
            //cout<<res[6]<<endl;
            int x;
            while(q--)
            {
                cin>>x;
                if(res[x]==10000)
                    puts("Sorry");
                else printf("%02d:%02d
    ",(res[x]+480)/60,(res[x]+480)%60);
            }
        }
        return 0;
    }
    
    /*
    2 2 7 5
    1 2 6 4 3 534 2
    3 4 5 6 7
    */
    

    1015:

    题目大意:给你两个数n。b,我们记还有一个数是m,将n转换为b进制然后再倒转再转换成10进制变成m,假设n和m都是素数,那么yes,否则no。

    直接模拟就好。

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn=1005;
    
    int a[maxn];
    int base;
    
    int isprime(int x)
    {
        if(x==1||x==0) return 0;
        for(int i=2;i<=sqrt(x+0.5);i++)
        {
            if(x%i==0) return 0;
        }
        return 1;
    }
    
    int verse(int x)
    {
        int p=x;
    
        int cnt=0;
        while(p)
        {
            a[cnt++]=p%base;
            p/=base;
        }
        int ans=0;
        for(int i=0;i<cnt;i++)
        {
            ans=ans*base+a[i];
        }
        return ans;
    }
    
    int main()
    {
        int x;
        while(cin>>x&&x>=0)
        {
            cin>>base;
            int y=verse(x);
            //cout<<y<<endl;
            if(isprime(x)&&isprime(y)) puts("Yes");
            else puts("No");
        }
        return 0;
    }
    
    /*
    73 10
    23 2
    23 10
    -2
    */
    

    1016:

    由于这个1016。真的被伤了。。。。

    题目大意:主题是算话费的,先给你24小时每小时内每分钟的资费。各自是00:00-01:00,01:00-02:00的每分钟话费,单位是美分,然后给你n个电话记录,每条记录会实username。月:天:时:分。然后是一个状态。online表示打电话。offline表示挂电话。

    所以我们要排序匹配。

    而题目中说了保证每一个人的记录是一个月份内的。

    而且假设某人的记录没一个能匹配的话就不打印他的账单。

    预计是自己的代码写挫了。。。


    (15分/25分)代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const double eps=1e-10;
    
    int rate[26];  //每小时里1分钟的价钱
    int n;  //多少个记录
    
    struct node
    {
        char name[25];
        char time[25];
        int month;
        int day;
        int hour;
        int minu;
        int fla;
    } bill[1005];
    
    struct nod
    {
        char ans1[25];
        char ans2[25];
        int curt;
        double mon;
    } ans[1005];
    
    int cmp(node p1,node p2)
    {
        if(strcmp(p1.name,p2.name)<0)
            return 1;
        else if(strcmp(p1.name,p2.name)==0&&strcmp(p1.time,p2.time)<0)
            return 1;
        return 0;
    }
    
    double cal1(int day,int hour,int minu)  //计算money
    {
        double ans=0;
        ans+=(double)day*rate[25]*60;
        for(int i=1; i<hour+1; i++)
            ans+=rate[i]*60;
        ans+=(double)rate[hour+1]*minu;
        return ans/100.0;
    }
    
    int cal2(int day,int hour,int minu)  //计算时间
    {
        return day*24*60+hour*60+minu;
    }
    
    void solve()
    {
        char ansname[25];
        int cnt;
        int month;
    
        cnt=0;
        int p=0;
    
        //cout<<bill[0].time<<" "<<bill[0].month<<endl;
        //for(int i=0; i<n; i++)
            //cout<<i<<" "<<bill[i].name<<" "<<bill[i].time<<" "<<bill[i].fla<<endl;
        while(p<n)  //最開始先找一个online的位置p
        {
            if(bill[p].fla==1)
            {
                strcpy(ansname,bill[p].name);
                month=bill[p].month;
                p++;
                break;
            }
            else p++;
        }
    
        //cout<<ansname<<" "<<month<<endl;
        //cout<<p<<endl;
    
        double total=0; //记录一个月的花费
    
        int flag=1;  //flag=1代表有online,
        //puts("fuck1");
        while(p<n)
        {
            //cout<<p<<"****"<<endl;
            if(strcmp(ansname,bill[p].name)!=0)
            {
                //cout<<"???

    ?

    "<<cnt<<endl; if(cnt>0) { printf("%s %02d ",ansname,month); for(int i=0; i<cnt; i++) { printf("%s %s %d $%.2f ",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon); } printf("Total amount: $%.2f ",total); total=0; cnt=0; } flag=0; while(p<n) //刚处理完一个人的,寻找下一个online的 { if(bill[p].fla==1) { strcpy(ansname,bill[p].name); month=bill[p].month; p++; flag=1; break; } else p++; } } else //说明当前是一个月一个人的。

    { if(bill[p].fla==0&&flag) //開始计算 { ans[cnt].curt=cal2(bill[p].day,bill[p].hour,bill[p].minu)- cal2(bill[p-1].day,bill[p-1].hour,bill[p-1].minu); ans[cnt].mon=cal1(bill[p].day,bill[p].hour,bill[p].minu)- cal1(bill[p-1].day,bill[p-1].hour,bill[p-1].minu); total+=ans[cnt].mon; char tmp1[25],tmp2[25]; for(int i=0; i<8; i++) { tmp1[i]=bill[p-1].time[i+3]; tmp2[i]=bill[p].time[i+3]; } tmp1[8]=tmp2[8]-''; strcpy(ans[cnt].ans1,tmp1); strcpy(ans[cnt++].ans2,tmp2); p++; flag=0; //cout<<p<<" hhe"<<endl; } else { flag=0; if(bill[p].fla==1) { flag=1; } p++; } } } if(cnt>0) { //puts("fuck"); printf("%s %02d ",ansname,month); for(int i=0; i<cnt; i++) { printf("%s %s %d $%.2f ",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon); } printf("Total amount: $%.2f ",total); total=0; cnt=0; } } int main() { int i; while(cin>>rate[1]) { rate[25]=0; rate[25]+=rate[1]; for(i=2; i<=24; i++) { cin>>rate[i]; rate[25]+=rate[i]; //rate[25]是24小时的总和 } char tmp1[25]; cin>>n; for(i=0; i<n; i++) { cin>>bill[i].name>>bill[i].time>>tmp1; if(strcmp(tmp1,"on-line")==0) //假设是1,表示接通,不是的话就是挂断 bill[i].fla=1; else bill[i].fla=0; strcpy(tmp1,bill[i].time); bill[i].month=(tmp1[0]-'0')*10+(tmp1[1]-'0'); bill[i].day=(tmp1[3]-'0')*10+(tmp1[4]-'0'); bill[i].hour=(tmp1[6]-'0')*10+(tmp1[7]-'0'); bill[i].minu=(tmp1[9]-'0')*10+(tmp1[10]-'0'); } sort(bill,bill+n,cmp); solve(); } return 0; } /* 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 10 CYLL 01:01:06:01 on-line CYLL 01:28:16:05 off-line CYJJ 01:01:07:00 off-line CYLL 01:01:08:03 off-line CYJJ 01:01:05:59 on-line aaa 01:01:01:03 on-line aaa 01:02:00:01 on-line CYLL 01:28:15:41 on-line aaa 01:05:02:24 on-line aaa 01:04:23:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 4 CYJJ 01:01:07:00 off-line CYJJ 01:01:05:59 on-line CYJJ 01:01:05:00 on-line CYJJ 01:01:07:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 2 CYJJ 01:01:08:00 on-line CYJJ 01:01:07:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 2 CYJJ 01:01:07:58 on-line CYJJ 01:01:07:59 off-line 10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 18 CYLL 01:01:06:01 on-line CYLL 01:01:07:00 off-line CYLL 01:01:08:03 on-line CYLL 01:01:08:09 off-line CYLL 01:01:08:09 on-line CYLL 01:02:00:01 off-line CYLL 01:28:15:41 on-line CYLL 01:29:02:24 on-line CYLL 01:30:23:59 off-line CYLL 01:30:24:59 off-line CYLL 01:30:25:00 off-line CYLL 01:30:25:25 off-line MQ 01:01:06:01 on-line MQ 01:02:03:04 on-line MQ 01:03:04:05 on-line MQ 01:03:04:06 off-line YF 01:02:03:04 on-line YF 01:02:03:05 on-line all dates will be within a single month. */


    网上有大神的满分代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct
    {
        char name[22];//名字
        int month;//月份
        int day;//天
        int hour;//时
        int minute;//分
        char tag[10];//on-line or off-line
    }record;
    
    int n;
    record *rd;
    int rate[24];//费率
    int count, start;//记录当前处理的这个用户的记录数目。和当前这个用户的第一条记录位置
    double totalCharge;//该用户该月的费用合计
    
    double charge(int sday, int shour, int sminute, int eday, int ehour, int eminute)//计算一条有效电话记录的时长和费用。并返回费用
    {
        double cost = 0;
        long time = 0;
    
        while(sday < eday)//先让天相等
        {
            time += (60 - sminute);
            cost += (60 - sminute) * rate[shour];
            sminute = 0; shour ++;//分化成0。时加1
            time += 60 * (24 - shour);
            while(shour < 24)
            {
                cost += 60 * rate[shour];
                shour ++;
            }
            shour = 0; sday ++;//时化成0。天加1
        }//天此时相等,时分为00:00
        while(shour < ehour)//再让时相等
        {
            time += (60 - sminute);
            cost += (60 - sminute) * rate[shour];
            sminute = 0; shour ++;
        }
        time += (eminute - sminute);
        cost += rate[ehour] * (eminute - sminute);
    
        printf("%ld $%.2lf
    ", time, cost / 100);
    
        return cost / 100;
    }
    
    void totalCount()//数出当前要处理的客户的总记录数目
    {
        int i;
        for(i = start + 1; i < n; i ++)
        {
            if(strcmp(rd[i].name, rd[i - 1].name) != 0)
            {
                break;
            }
            else
            {
                count ++;
            }
        }
    }
    
    int comp_name(const void *a, const void *b)
    {
        record c = *(record *)a;
        record d = *(record *)b;
    
    
        if(strcmp(c.name, d.name) <= 0) return -1;
        else return 1;
    }
    
    int comp_time(const void *a, const void *b)
    {
        record c = *(record *)a;
        record d = *(record *)b;
    
        if(c.day < d.day) return -1;
        else if(c.day > d.day) return 1;
        else
        {
            if(c.hour < d.hour) return -1;
            else if(c.hour > d.hour) return 1;
            else
            {
                if(c.minute < d.minute) return -1;
                else return 1;
            }
        }
    }
    
    int main()
    {
        int i;
        int flag;//1应该出现offline, 0应该出现online
        int onpos;//记录近期有效的on-line记录位置,为了算出charge
        int sign;//0表示该客户名字和月份还没有输出。1表示已输出
        
    
        while(scanf("%d", &rate[0]) != EOF)
        {
            for(i = 1; i < 24; i ++)
            {
                scanf("%d", &rate[i]);
            }
            scanf("%d", &n);
            rd = (record *)malloc(n * sizeof(record));
            for(i = 0; i < n; i ++)
            {
                scanf("
    %s %d:%d:%d:%d %s", rd[i].name, &rd[i].month, &rd[i].day, &rd[i].hour, &rd[i].minute, rd[i].tag);
            }
            qsort(rd, n, sizeof(record), comp_name);//先将记录按字母表顺序分类
            count = 1; start = 0; totalCount(); sign = 0;
            while(start < n)//整个记录表还没处理完
            {
                qsort(rd + start, count, sizeof(record), comp_time);
                flag = 0;
                totalCharge = 0;
                for(i = start; i < start + count; i ++)//处理该客户
                {
                    if(flag == 0)//期待出现online,假设是offline跳过
                    {
                        if(rd[i].tag[1] == 'f')//off-line
                        {
                            continue;
                        }
                        else//on-line
                        {
                            onpos = i;
                            flag = 1;
                        }
                    }
                    else//期待出现offline,假设是online则更新onpos
                    {
                        if(rd[i].tag[1] == 'n')//on-line
                        {
                            onpos = i;
                        }
                        else//off-line
                        {
                            if(sign == 0)
                            {
                                printf("%s %02d
    ", rd[start].name, rd[start].month);
                                sign = 1;
                            }
                            printf("%02d:%02d:%02d %02d:%02d:%02d ", rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute);
                            totalCharge += charge(rd[onpos].day, rd[onpos].hour, rd[onpos].minute, rd[i].day, rd[i].hour, rd[i].minute);
                            flag = 0;
                        }
                    }
                }
                if(sign == 1)
                {
                    printf("Total amount: $%.2lf
    ", totalCharge);
                }
                start += count; count = 1; totalCount(); sign = 0;
            }
        }
        return 0;
    }

    真心被玩儿出内伤了。


  • 相关阅读:
    [算法] 神秘数
    教你在Access数据库中如何使用SQL
    亚宇工资管理系统早年制作的一个很小的商业软件[源码和软件截图]
    亚宇工资管理系统早年制作的一个很小的商业软件[源码和软件截图]
    getkeyTw
    一个硬盘的感人的爱情故事!只此一篇
    码农如何快速打造一个有设计感的网站
    NK.bin和NK.nb0学习
    WINCE6.0 + S3C2443的启动过程nboot篇
    S3C2443时钟管理
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7091137.html
Copyright © 2020-2023  润新知