浙大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\n",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\n",(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\n",ansname,month);
                for(int i=0; i<cnt; i++)
                {
                    printf("%s %s %d $%.2f\n",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon);
                }
                printf("Total amount: $%.2f\n",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]-‘\0‘;
                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\n",ansname,month);
        for(int i=0; i<cnt; i++)
        {
            printf("%s %s %d $%.2f\n",ans[i].ans1,ans[i].ans2,ans[i].curt,ans[i].mon);
        }
        printf("Total amount: $%.2f\n",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\n", 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("\n%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\n", 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\n", totalCharge);
            }
            start += count; count = 1; totalCount(); sign = 0;
        }
    }
    return 0;
}

真心被玩儿出内伤了。

时间: 2024-10-18 06:28:13

浙大PAT考试1013~1016(最伤的一次。。)的相关文章

浙大PAT考试1077~1080(2014上机复试题目)

题目地址:点击打开链接 还是太弱. . 英文太差.,, 预计要等待被虐了.. 1077 找最长的公共后缀,暴力就能够写: #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> using namespace std; char a[105][1005]; int milen;

PAT乙级 1013. 数素数 (20)

1013. 数素数 (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 令Pi表示第i个素数.现任给两个正整数M <= N <= 104,请输出PM到PN的所有素数. 输入格式: 输入在一行中给出M和N,其间以空格分隔. 输出格式: 输出从PM到PN的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格. 输入样例: 5 27 输出样例: 11 13 17 19 23 29 31 37 4

PAT Basic 1013

1013 数素数 令P~i~表示第i个素数.现任给两个正整数M <= N <= 10^4^,请输出P~M~到P~N~的所有素数. 输入格式: 输入在一行中给出M和N,其间以空格分隔. 输出格式: 输出从P~M~到P~N~的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格. 输入样例: 5 27 输出样例: 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 题解:这道题其实就是打素数表,

pat甲级1013

1013 Battle Over Cities (25)(25 分) It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any

PAT乙级1013.数素数

1013 数素数 (20)(20 分) 令P~i~表示第i个素数.现任给两个正整数M <= N <= 10^4^,请输出P~M~到P~N~的所有素数. 输入格式: 输入在一行中给出M和N,其间以空格分隔. 输出格式: 输出从P~M~到P~N~的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格. 输入样例: 5 27 输出样例: 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 #inc

PAT 甲级 1013 Battle Over Cities (25 分)(图的遍历,统计强连通分量个数,bfs,一遍就ac啦)

1013 Battle Over Cities (25 分) It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any oth

PAT乙级1013

1013 数素数 (20分) 题目地址:https://pintia.cn/problem-sets/994805260223102976/problems/994805309963354112 令\(P_i\) 表示第 i 个素数.现任给两个正整数 M≤N≤\(10^4\),请输出 \(P_M\) 到 \(P_N\) 的所有素数. 输入格式: 输入在一行中给出 M 和 N,其间以空格分隔. 输出格式: 输出从 \(P_M\) 到 \(P_N\) 的所有素数,每 10 个数字占 1 行,其间以空

PAT Advanced 1013 Battle Over Cities (25分)

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of

PAT:1013. 数素数 (20) AC

#include<stdio.h> #include<math.h> bool isprime(int num) { int sqr=(int)sqrt(num*1.0); //[skill]判断素数只要判断到开平方就可以了 for(int i=2 ; i<sqr+1 ; ++i) if(num%i==0) return 0; return 1; } int main() { int l,r; scanf("%d%d",&l,&r); in