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;
}