PAT 1016 Phone Bills (25)

题目说明:

输入: 

24个小时每个时段通话价格 美分/分钟 toll[]

通话记录数N

N行通话记录:名字name 时间date 状态status (on-line表示通电话,off-line表示挂电话)

输出:每个客户的账单,按照客户名字的字典顺序输出,每个客户的多条记录按照时间顺序输出。on-line和off-line配对的才是有效记录。

注意点:若客户没有有效记录,则不打印这个客户的账单。

It is guaranteed that at least one call is well paired in the input. 保证至少有一条有效记录,但不是每个客户都有有效记录。

思路:先排序所有记录,按照姓名-时间升序排列,然后逐个计算每个客户的通话记录和话费。话费计算是先计算出从0时刻到通电话时刻的话费和到挂电话时刻的话费,两部分相减得到本条记录的话费。

代码:

#include<iostream>
#include<fstream>
#include<algorithm>
using namespace std;
#define MAXN 1005
int toll[30];
int N;

int countdayprice();

struct Record{
	string name;
	string date;
	int month; 
	int day;
	int hour;
	int min;
	string status;
}record[MAXN];

bool cmp(const Record &a,const Record &b){
	//以姓名排序,姓名相同以时间排序 
	if(a.name<b.name)
		return true;
	else if(a.name==b.name){
		if(a.date<b.date)
			return true;
		else 
			return false;
	}
	else
		return false;
}
int counttime(int s,int e){
	int time;
	time=record[e].day*60*24+record[e].hour*60+record[e].min
	-(record[s].day*60*24+record[s].hour*60+record[s].min);
	return time;
}
//计算从0到某个时间的总花费 
int countprice(int day,int hour,int min){
	int price=0;
	for(int i=0;i<hour;i++){
		price+=toll[i];
	}
	price*=60;
	price+=toll[hour]*min;
	price+=countdayprice()*day;
	return price;
}
//计算每条记录的话费 
float countrecordprice(int s,int e){
	float price;
	//结束减去开始 
	price=countprice(record[e].day,record[e].hour,record[e].min)-
	countprice(record[s].day,record[s].hour,record[s].min);
	return price/100;
}
//每天一整天的话费 
int countdayprice(){
	int dayprice=0;
	for(int i=0;i<24;i++){
		dayprice+=toll[i];
	}
	dayprice*=60;
	return dayprice;
}
int main(){
	#ifdef ONLINE_JUDGE
	#else 
	ifstream cin("aa.txt");
	#endif
	
	for(int i=0;i<24;i++){
		cin>>toll[i];
	}
	cin>>N;
	for(int i=0;i<N;i++){
		cin>>record[i].name>>record[i].date>>record[i].status;
		string date=record[i].date;
		record[i].month=(date[0]-48)*10+(date[1]-48);
		record[i].day=(date[3]-48)*10+(date[4]-48);
		record[i].hour=(date[6]-48)*10+(date[7]-48);
		record[i].min=(date[9]-48)*10+(date[10]-48);		
	}

	//排序所有记录。
	sort(record,record+N,cmp);

	string name="0"; 
	int start;
	int end;
	float totalamount=0;
	bool flagon=false;//on-off配对标记 
	bool flagname=false;//同一个用户的标记 
	for(int i=0;i<N;i++){
		if(name!=record[i].name){
			if(totalamount>0){
				//输出总话费 
				printf("Total amount: $%.2f\n",totalamount);
			}
			name=record[i].name;
			
			flagon=false;
			flagname=false;
			totalamount=0;	
		}
		if(record[i].status=="on-line"){
			start=i;
			flagon=true;
		}
		else if(record[i].status=="off-line"){
			if(flagon){
				//输出name信息 
				if(!flagname){
					flagname=true;
					cout<<name;//string 用cout 
					printf(" %02d\n",record[i].month);
				}
				flagon=false;
				end=i;
				//输出一条记录 
				printf("%02d:%02d:%02d %02d:%02d:%02d ",
				record[start].day,record[start].hour,record[start].min,
				record[end].day,record[end].hour,record[end].min);
				float recordprice=countrecordprice(start,end);
				printf("%d $%.2f\n",counttime(start,end),
				recordprice);
				totalamount+=recordprice; 
			}
		}
		//最后一条记录的总话费输出 
		if(i==N-1&&totalamount>0)
			printf("Total amount: $%.2f\n",totalamount);
	}	
	return 0;
}

之前在排序记录的过程中出现了一些问题,开始是采用两次sort,先对时间进行排序,再对姓名进行排序,但是结果有时会出错。改了cmp函数用一次sort排序就可以了。后来发现sort是不稳定排序,如果要这样做必须用stable_sort进行稳定排序。

string类型只能用cin,cout,不能用scanf,printf ,若要用printf,只能用printf("%s",str.c_str())。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值