PTA 1016 Phone Bills (25 分)

模拟题,细节很多,操作麻烦,实属不易,纪念一下。

重要是细节的处理

  • 如果没有花费不必输出。
  • 对于每一个人,把off和on分别储存在两个结构体中,结构体保存对应的时间。
  • 对于匹配的一对,可以先找到on[i]对应的下一个最近的off[f],在验证off[j]上一个最近的on是非为on[i]。
  • 处理花费,一秒一秒加。cent转dollor要除以100。

代码

#include <bits/stdc++.h>
using namespace std;
int const N = 1000 + 10;
typedef pair<string,int>psi;
struct Node{
	int mon,dd,hh,mm,tot;
	void add(){
		mm++;
		if(mm == 60)	hh++,	mm = 0;
		if(hh == 24)	dd++,	hh = 0;
		tot++;
	}
	bool operator < (const Node& e)const{
		return tot < e.tot;
	}
};
struct Node2{
	Node st,ed;
	int tottim;
	double totbill;
};
vector<Node2>ans;
vector<Node>on[N],off[N];
map<string,int>mp;
string rmp[N];
vector<psi>v;
int n,cnt;
double cent[N];
double getbill(Node st,Node ed){
	double sum = 0;
	while(st < ed){
		sum += cent[st.hh];
		st.add();
	}
	return sum / 100;
}
void print(int m,double totbill){
	cout<<rmp[m]<<' ';	printf("%02d\n",on[m][0].mon);
	for(int i=0;i<ans.size();i++){
		if(fabs(ans[i].totbill) <= 1e-8)	continue;
		printf("%02d:%02d:%02d ",ans[i].st.dd,ans[i].st.hh,ans[i].st.mm);
		printf("%02d:%02d:%02d ",ans[i].ed.dd,ans[i].ed.hh,ans[i].ed.mm);
		printf("%d $%.2f\n",ans[i].tottim,ans[i].totbill);
	}
	printf("Total amount: $%.2f\n",totbill);
}
void solve(int m){
	int j = 0,k;
	double totbill = 0;
	sort(on[m].begin(),on[m].end());
	sort(off[m].begin(),off[m].end());
	ans.clear();
	for(int i=0;i<on[m].size();i++){
		while(j < off[m].size() && off[m][j].tot < on[m][i].tot)	j++; 	 
		if(j < off[m].size() && off[m][j].tot >= on[m][i].tot){  
			k = on[m].size() - 1;
			while(k >= 0 && off[m][j].tot < on[m][k].tot)	k--;
			if(k == i){  				
				int tim = off[m][j].tot - on[m][i].tot;
				double bill = getbill(on[m][i],off[m][j]);
				if(fabs(bill) <= 1e-8)	continue;
				totbill += bill;
				ans.push_back(Node2{on[m][i],off[m][j],tim,bill});
			}
		}	
	}
	if(fabs(totbill) > 1e-8)	print(m,totbill);  
}
int main(){
	for(int i=0;i<24;i++)	scanf("%lf",&cent[i]);
	cin>>n;
	for(int i=1;i<=n;i++){
		string name,type;
		int mon,dd,hh,mm;
		cin>>name;
		scanf("%d:%d:%d:%d",&mon,&dd,&hh,&mm);
		cin>>type;
		if(!mp[name]){
			mp[name] = ++cnt,	rmp[cnt] = name;
			v.push_back(psi(name,cnt)); 
		}
		if(type == "on-line")	on[mp[name]].push_back(Node{mon,dd,hh,mm,mm+hh*60+dd*24*60});
		else	off[mp[name]].push_back(Node{mon,dd,hh,mm,mm+hh*60+dd*24*60});
	}
	sort(v.begin(),v.end());  
	for(int i=0;i<v.size();i++)	solve(v[i].second);
	return 0;
}

 

posted @ 2019-10-30 09:51  月光下の魔术师  阅读(1)  评论(0)    收藏  举报