PAT 1013-1016 <Battle Over Cities> <Waiting in Line> <Reversible Primes> <Phone Bills>

1013 Battle Over Cities

分析

考察点:图的遍历、连通分支的计算
基础题

代码

//
//  main.cpp
//  PAT-testcpp
//
//  Created by hwl on 2021/1/15.
//
#include<bits/stdc++.h>
using namespace std;
int vis[1001] = {0};
int lost_c;
int n; //图中的节点数目
void dfs(vector<vector<int>> &mat,int start)
{
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]&&mat[start][i]&&i!=lost_c)
        {
            vis[i] = 1;
            dfs(mat,i);
        }
    }
    return;
}
int main(){
    int m,k;
    cin>>n>>m>>k;
    vector<vector<int>> mat(n+1,vector<int>(n+1,0));
    for(int i=0;i<m;i++)
    {
        int from,to;cin>>from>>to;
        mat[from][to] = 1;
        mat[to][from] = 1;
    }
    vector<int> ans;
    for(int i=0;i<k;i++)
    {
        for(int j=0;j<1001;j++)
        {
            vis[j]=0;   //每次都要更新vis
        }
        int components = 0;
        cin>>lost_c;
        for(int j=1;j<=n;j++)
        {
            if(j==lost_c) continue;
            if(!vis[j])
            {
                components++;
                dfs(mat,j);
            }
        }
        ans.push_back(components-1);
    }

    for(int i=0;i<ans.size();i++)
        cout<<ans[i]<<endl;
    return 0;
}

1014 Waiting in Line

分析

模拟题,根据题目的意思模拟就好
大致的思路是根据每一个来到的客户,确定他的能获得窗口资源的时间和结束的时间即可。
这道题比较容易搞晕的是初始状态(前N * M个人的时候)要注意和后面状态稳定(即达到N * M个人)之后的区分

有几个注意点:
1.窗口的编号最好是从0开始,方便后面的排序(如果用的优先队列就可以不用管)
2.出队时要先判空
3.更新队伍空闲时间时要注意初始状态(未满M个人时)
4.C中的格式化输出

代码

//
//  main.cpp
//  PAT-testcpp
//
//  Created by hwl on 2021/1/15.
//
#include<bits/stdc++.h>
using namespace std;
struct customer{
    int serve_time;
    int end_time;
    int process_time;
};
struct window{
    int line_free_time;     //是指窗口队列空闲的时间
    int window_free_time;   //是指窗口空闲的时间
    queue<customer> line;   //排队的customer
    int id;         //编号
    
};
int cmp(window a,window b)
{
    //排序的优先级: 空闲时间 > 排队人数 > 窗口编号
    if(a.line_free_time == b.line_free_time)
    {
        if(a.line.size() == b.line.size())
            return a.id<b.id;
        return a.line.size()<b.line.size();
    }
    return a.line_free_time<b.line_free_time;
}
int main(){
    int n,m,k,q;
    cin>>n>>m>>k>>q;
    vector<window> windows(n);
    vector<customer> customers(k+1);
    for(int i=1;i<=k;i++)
        cin>>customers[i].process_time;
   
    vector<int> query(q);
    
    for(int i=0;i<q;i++)
        cin>>query[i];
    
    //初始化每个window的free_time和id
    for(int i=0;i<n;i++){
        windows[i].line_free_time = 0;
        windows[i].window_free_time = 0;
        windows[i].id = i;  //窗口从0开始编号,方便后面的排序(这点要注意)
    }
    
    //对于每一个customer,计算servertime和endtime
    for(int i=1;i<=k;i++)
    {
        //先找一个满足要求的window
        sort(windows.begin(),windows.end(),cmp);
        customers[i].serve_time = windows[0].window_free_time;
        customers[i].end_time = windows[0].window_free_time+customers[i].process_time;
        
        //队首的人离开
        if(windows[0].line.size()>0&&windows[0].line_free_time!=0)
            windows[0].line.pop();
        //入队
        windows[0].line.push(customers[i]);
        
        //更新window的时间
        if(windows[0].line.size()>=m)
            windows[0].line_free_time+=windows[0].line.front().process_time;
        windows[0].window_free_time+=customers[i].process_time;
        

    }
    
    //输出答案
    for(int i=0;i<q;i++)
    {
        if(customers[query[i]].serve_time>=540)
            cout<<"Sorry"<<endl;
        else{
            printf("%02d:%02d\n",customers[query[i]].end_time/60+8,customers[query[i]].end_time%60);
        }
    }
    return 0;
}



1015 Reversible Primes

分析

基础题

代码

//
//  main.cpp
//  PAT-testcpp
//
//  Created by hwl on 2021/1/15.
//
#include<bits/stdc++.h>
using namespace std;
int isprime(int n)
{
    if(n<2)
        return 0;
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
            return 0;
    }
    return 1;
}
int trans2Radix_d_and_reverse(int n,int d)
{
    string str = "";
    while(n)
    {
        str+=n%d+'0';
        n/=d;
    }
    int len = str.size();
    int ans = 0;
    for(int i=0;i<len;i++)
    {
        ans+=pow(d,i)*(str[len-i-1]-'0');
    }
    return ans;
}
int main(){
    int n,d;
    while (cin>>n&&n>=0) {
        cin>>d;
        if(isprime(n)&&isprime(trans2Radix_d_and_reverse(n,d)))
        {
            cout<<"Yes"<<endl;
        }
        else{
            cout<<"No"<<endl;
        }
    }
    return 0;
}

1016 Phone Bills

分析

基础题,有些细节的地方注意下就好
1.把时间全部转成分钟做起来更方便
2.配对的时候不能用栈的方式实现,按照题目要求,如果出现 on on off off,这种情况,需要配对的是中间两个,其余的丢弃

代码

//
//  main.cpp
//  PAT-testcpp
//
//  Created by hwl
//
#include<bits/stdc++.h>
using namespace std;
struct item{
    string name;
    string time;
    string status;
};
int cmp(item a,item b)
{
    if(a.name==b.name)
    {
        return a.time<b.time;
    }
    return a.name<b.name;

}
int main(){
    vector<int> rate(24);
    for(int i=0;i<24;i++)
        cin>>rate[i];
    int n;
    cin>>n;
    vector<item> v_item(n);
    for(int i=0;i<n;i++)
    {
        cin>>v_item[i].name>>v_item[i].time>>v_item[i].status;
    }

    //按照时间顺序排好序
    sort(v_item.begin(),v_item.end(),cmp);

    map<string,vector<pair<string,string>>> map_pair;  //pair : on-line和off-line的结束时间
    //开始配对 on和off
    //这个地方不能用栈来实现,不符合题意
    for(int i=0;i<v_item.size()-1;i++)
    {
        if(v_item[i].status=="on-line"&&v_item[i+1].status=="off-line"&&v_item[i].name==v_item[i+1].name)
        {
            map_pair[v_item[i].name].push_back(pair<string, string>{v_item[i].time,v_item[i+1].time});
        }
    }

    //处理日期
    //需要用到string的一些函数来做处理
    /*
        1.计算dd:HH:mm之间的时间间隔最方便的办法就是把时间全部转成分钟
        2.计算rate的价格,以60min为间隔作为推进:知道了开始的hh,然后开始往后以推进
    */
    for(auto it=map_pair.begin();it!=map_pair.end();it++)
    {
        cout<<it->first<<" "<<it->second[0].first.substr(0,2)<<endl;
        vector<pair<string,string>> v = it->second;
        double sum_price = 0;
        for(int i=0;i<v.size();i++)
        {
            int start_HH = atoi(v[i].first.substr(6,2).c_str());
            int start_mm = atoi(v[i].first.substr(9,2).c_str());
            int time_gap =  (atoi(v[i].second.substr(3,2).c_str())*24*60+
                             atoi(v[i].second.substr(6,2).c_str())*60+
                             atoi(v[i].second.substr(9,2).c_str()))-
                            (atoi(v[i].first.substr(3,2).c_str())*24*60+
                            atoi(v[i].first.substr(6,2).c_str())*60+
                             atoi(v[i].first.substr(9,2).c_str()));//开始时间-结束时间
            double price = 0;
            int k = start_HH;
            int tmp;
            //这里做一个判断:有没有横跨小时
            if(time_gap+start_mm>60){
                price += rate[k]*(60-start_mm)*0.01;              
                tmp = time_gap - (60-start_mm);
            }
            else{
                price += time_gap*rate[k]*0.01;
                tmp = 0;
            }
            k=(k+1)%24;
            //以60为单位推进
            while (tmp>=60) {
                tmp-=60;
                price+=rate[k]*60*0.01;
                k=(k+1)%24;
            }
            price+=rate[k]*tmp*0.01;
            sum_price+=price;
            
            //输出 开始-结束-时间间隔-price
            cout<<v[i].first.substr(3,8)<<" "<<v[i].second.substr(3,8)<<" "<<time_gap<<" ";
            printf("$%.2f\n",price);
        }
        cout<<"Total amount: ";
        printf("$%.2f\n",sum_price);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值