PAT 甲级 1016. Phone Bills (25)


题目:点击打开链接

思路:1.根据输入,将通话信息根据用户名、时间进行排序

            2.排序完后,进行信息筛选:在计算单次通话话费时,先判断两条信息是否属于同一用户,再判断其是否为一on-line ,一off-line的情况;

            3.在计算话费时,注意时间跨度

代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;

//int toll[24]={10,10,10,10,10,10,20,20,20,15,15,15,15,15,15,15,20,30,20,15,15,10,10,10};
int toll[24];
struct customer
{
	string name;
	string month;
	string t;
        int time;     //时间记录
	bool record; //拨打or挂断
	bool operator<(const customer &a)const
	{
		if(name!=a.name)
			return name<a.name;
		else
			return time<a.time;
	}

};


//计算时间
int cal_time(string a)
{
	int time=0;
	time=(a[9]-'0')*10+a[10]-'0';
	time+=((a[6]-'0')*10+a[7]-'0')*60;
	time+=((a[3]-'0')*10+a[4]-'0')*60*24;
	return time;
}
//计算话费,这里要注意时间隔天的情况
int cal_cost(int begin_t,int end_t)
{
	int c=0;
	int h1=(begin_t/60)%24;   //起始小时
	int t=end_t-begin_t;
	begin_t-=(begin_t/60/24*60*24);
	end_t=begin_t+t;
	int h2;
	while(h1<(end_t/60))
	{
		h2=h1%24;
		c+=toll[h2]*((h1+1)*60-begin_t);		
		++h1;
		begin_t=h1*60;
	}
	h2=h1%24;
	c+=toll[h2]*(end_t-begin_t);
	return c;

}

int main()
{
	//输入
	int i=0;
	for(;i<24;++i)
		scanf("%d",toll+i);
	int N;
	cin>>N;
	vector<customer> C(N);
	//信息输入
	string T,R;
	for(i=0;i<N;++i)
	{
		cin>>C[i].name>>T>>R;
		C[i].time=cal_time(T);
		C[i].month=T.substr(0,2);    //这两部分保存,便于输出
		C[i].t=T.substr(3,8);
		if(R=="on-line")
			C[i].record=0;
		else
			C[i].record=1;
	}

	sort(C.begin(),C.end()); //排序

	string name;
	int total_time=0;
	int total_cost=0;
	int cost;
	bool flag=0;
	for(i=1;i<N;++i)
	{
		if(C[i].record==1 && C[i-1].record==0 && C[i].name==C[i-1].name)//表明信息有效
		{
			if(C[i].name!=name)     //出现换人的情况
			{
				if(flag)            //判断是否为首次输出,若为首次输出,则这一部分不必输出
				{
				  cout<<"Total amount: $";
				  printf("%d.%02d\n",total_cost/100,total_cost%100);
				  total_cost=0;
				}
				name=C[i].name;
				cout<<name<<" "<<C[i].month<<endl;
				flag=1;
			}
			total_time=C[i].time-C[i-1].time;		
			cost=cal_cost(C[i-1].time,C[i].time);
			total_cost+=cost;
			cout<<C[i-1].t<<" "<<C[i].t<<" ";
			printf("%d $%d.%02d\n",total_time,cost/100,cost%100);

		}

	}
	cout<<"Total amount: $";
	printf("%d.%02d\n",total_cost/100,total_cost%100);
	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值