1016. Phone Bills 解析

直接把时间化成以秒为单位 排序 匹配 计算就好。

……………………更新线…………………………

这里会遇到上一个人名on下一个人名接着off的情况需要注意下

重新写了下代码,感觉清爽了一点

#include <iostream>
#include <algorithm>
#include <climits>
#include <cstring>
#include <vector>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <set>

#define MAX 1010

using namespace std;

double rate[24];

struct node{
	string name;
	int month;
	int dd;
	int hh;
	int mm;
	int t_int;
	int tag;
};

struct dounode{
	node n1;
	node n2;
	int SumMin;
	double sum;
};

struct ansnode{
	string name;
	int month;
	vector <dounode> list;
	double sum;
	ansnode(){sum = 0;};
};

node l[MAX];
ansnode ans[MAX]; 

string on = "on-line";
string off = "off-line";

int n;

bool cmp(node n1 ,node n2){
	if(n1.name != n2.name)
		return n1.name < n2.name;
	else
		return n1.t_int < n2.t_int;
}

double rateCalculate(node n1 ,node n2,int & sumh){
	double nowrate = 0;
	if(n1.dd == n2.dd){//同一天
		if(n1.hh == n2.hh){//同一小时
			nowrate += rate[n1.hh] * (n2.mm - n1.mm);
			sumh += (n2.mm - n1.mm);
		}
		else{//不同小时
			nowrate += rate[n1.hh] * (60 - n1.mm);
			sumh += (60 - n1.mm);
			nowrate += rate[n2.hh] * n2.mm;
			sumh += n2.mm;
			for(int h = n1.hh + 1; h < n2.hh;h++){
				nowrate += rate[h] * 60;
				sumh += 60;
			}	
		}
	}
	else{//不同天
		sumh += (60 - n1.mm);
		sumh += n2.mm;
		nowrate += rate[n1.hh] * (60 - n1.mm);
		for(int h = n1.hh + 1 ; h < 24; h++){
			nowrate += rate[h] * 60;
			sumh += 60;
		}
		nowrate += rate[n2.hh] * n2.mm;
		for(int h = 0 ;h < n2.hh;h++){
			nowrate += rate[h] * 60;
			sumh += 60;
		}
		double day = 0;
		for(int i = 0 ; i < 24 ;i++)
			day += rate[i] * 60;
		nowrate += day * (n2.dd - n1.dd -1);
		sumh += (n2.dd - n1.dd -1) * 24 * 60;
	}
	return nowrate;
}

int main(){

	for(int i = 0; i < 24 ;i ++){
		scanf("%lf",&rate[i]);
		rate[i] /= 100;
	}

	scanf("%d",&n);

	for(int i = 0 ; i < n ;i++){
		string tag;
		string t_str;
		cin >> l[i].name >> t_str >> tag;
		if(tag == on)
			l[i].tag = 0;
		else 
			l[i].tag = 1;
		l[i].month = (t_str[0]-'0') * 10 + (t_str[1]-'0');
		l[i].dd = (t_str[3]-'0') * 10 + (t_str[4]-'0');
		l[i].hh = (t_str[6]-'0') * 10 + (t_str[7]-'0');
		l[i].mm = (t_str[9]-'0') * 10 + (t_str[10]-'0');
		l[i].t_int = l[i].dd * 24 * 60 + l[i].hh * 60 + l[i].mm;
	}
	sort(l,l+n,cmp);

	
	int pre = 0;
	string nowName = " ";
	int no = -1;
	int c = 0;
	bool pair = false;
	for(int i = 0 ; i <n ;i++){
		if(!pair && l[i].tag == 1)
			continue;
		else if(!pair && l[i].tag == 0){
			pair = true;
			pre = i;
		}
		else if(pair && l[i].tag == 0){
			pre = i;
		}
		else{
			if(l[pre].name == l[i].name){//同一个人的电话
				if(nowName != l[pre].name){
					no++;c++;
					nowName = l[pre].name;
					ans[no].name = nowName;
					ans[no].month = l[pre].month;
				}
				dounode t_dou;
				t_dou.SumMin = 0;
				t_dou.sum = rateCalculate(l[pre],l[i],t_dou.SumMin);		
				t_dou.n1 = l[pre];
				t_dou.n2 = l[i];
				ans[no].list.push_back(t_dou);
				ans[no].sum += t_dou.sum;
				ans[no].name = nowName;				
			}
			pair = false;
		}
	}

	for(int i = 0; i < c ;i++){
		cout << ans[i].name ;
		printf(" %02d\n",ans[i].month);
		for(int j = 0 ; j < ans[i].list.size();j++){
			printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.02lf\n",ans[i].list[j].n1.dd,ans[i].list[j].n1.hh,ans[i].list[j].n1.mm,ans[i].list[j].n2.dd,ans[i].list[j].n2.hh,ans[i].list[j].n2.mm,ans[i].list[j].SumMin,ans[i].list[j].sum);
		}
		printf("Total amount: $%.02lf\n",ans[i].sum);
	}
	


	return 0;
}
……………………………………完……………………………………

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

struct Node {
	string name;
	string time;
	string state;
};

int char2int(char i) {
	
	int result = 0;
	
	switch (i)
	{
	case '1': result = 1; break;
	case '2': result = 2; break;
	case '3': result = 3; break;
	case '4': result = 4; break;
	case '5': result = 5; break;
	case '6': result = 6; break;
	case '7': result = 7; break;
	case '8': result = 8; break;
	case '9': result = 9; break;
	case '0': result = 0; break;
	default:
		break;
	}

	return result;
}



int str2day(string s) {
	int day = 0;
	day = char2int(s[3]) * 10 + char2int(s[4]);
	return day;
}

int str2hour(string s) {
	int hour = 0;
	hour = char2int(s[6]) * 10 + char2int(s[7]);
	return hour;
}

int str2minute(string s) {
	int minute = 0;
	minute = char2int(s[9]) * 10 + char2int(s[10]);
	return minute;
}

int CalRate(string time1, string time2, vector <int> rate) {//M1 < M2
	int D1, D2, H1, H2, M1, M2;
	D1 = str2day(time1);
	D2 = str2day(time2);
	H1 = str2hour(time1);
	H2 = str2hour(time2);
	M1 = str2minute(time1);
	M2 = str2minute(time2);

	int Sum = 0;

	if (D1 == D2) { //同一天
		if (H1 == H2) {//同一小时
			Sum += (M2 - M1)* rate[H1];
			return Sum;
		}
		else{//不同小时
			Sum += (60 - M1) * rate[H1];
			Sum += M2 * rate[H2];
			for (int i = H1+1; i < H2; i++)
				Sum += 60 * rate[i];
			return Sum;
		}
	}
	else{ //不同天
		Sum += (60 - M1)* rate[H1];
		for (int i = H1 + 1; i < 24; i++) {
			Sum += 60 * rate[i];
		}
		Sum += M2 * rate[H2];
		for (int i = 0; i < H2; i++) {
			Sum += 60 * rate[i];
		}
		for (int i = D1 + 1; i < D2; i++) {
			for (int j = 0; j < 24; j++) {
				Sum += rate[j] * 60;
			}
		}
		return Sum;
	}

	

}

void PrintTime(string s) {
	for (int i = 3; i <= 10; i++) {
		cout << s[i];
	}
}



void TotalRate(vector <Node> list ,vector <int> rate) { //对一个用户的账单进行生成

	bool tag = false;//是否匹配
	bool Head = true;//又没有显示Head
	bool HaveBill = false;
	float SumRate = 0;
	int time = 0;
	Node pre; //匹配前
	

	//cout << list[0].name << " " << list[0].time[0] << list[0].time[1] << endl;

	for (int i = 0; i < list.size(); i++) {
		if (!tag && list[i].state == "off-line")//前面没有on 却有off 忽略
			continue;
		else if (!tag && list[i].state == "on-line") {//前面没有on 后面weion pre等于该数
			tag = true;
			pre = list[i];
		}
		else if (tag && list[i].state == "on-line") { //前面有on 后面还有on 更新pre
			pre = list[i];
		}
		else {//匹配成功
			if(Head){
				cout << list[i].name << " " << list[i].time[0] << list[i].time[1] << endl;
				Head = false;
				HaveBill = true;
			}
			tag = false;
			int PreTime = str2day(pre.time) * 24 * 60 + str2hour(pre.time) * 60 + str2minute(pre.time);
			int Time = str2day(list[i].time) * 24 * 60 + str2hour(list[i].time) * 60 + str2minute(list[i].time);
			int gapTime = Time - PreTime;
			float tempRate = CalRate(pre.time, list[i].time, rate);
			float tR = tempRate / 100;
			SumRate += tR;

			PrintTime(pre.time); 
			cout << " ";
			PrintTime(list[i].time);
			cout << " " << gapTime << " $";
			printf("%.02f", tR);
			cout << endl;
		}
	}


	if (HaveBill) {
		cout << "Total amount: $";
		printf("%.2f", SumRate);
		cout << endl;
	}
}





bool cmp(Node N1 ,Node N2) {
	if (N1.name < N2.name)
		return true;
	else if (N1.name == N2.name && str2day(N1.time) < str2day(N2.time))
		return true;
	else if (N1.name == N2.name && str2day(N1.time) == str2day(N2.time) && str2hour(N1.time) < str2hour(N2.time))
		return true;
	else if (N1.name == N2.name && str2day(N1.time) == str2day(N2.time) && str2hour(N1.time) == str2hour(N2.time) && str2minute(N1.time) < str2minute(N2.time))
		return true;
	else
		return false;
}


int main() {
	
	vector <int> rate;	
	int tempRate;
	for (int i = 0; i < 24; i++) {
		cin >> tempRate;
		rate.push_back(tempRate);
	}

	int N;//记录数
	cin >> N;

	Node * record = new Node[N];
	set<string> r;

	for (int i = 0; i < N; i++) {
		cin >> record[i].name >> record[i].time >> record[i].state;
		r.insert(record[i].name);
		
	}


	sort(record, record + N, cmp);//对记录进行排序
	vector <Node> * List = new vector<Node>[r.size()]; //对不同用户进行分组
	string temp = record[0].name;
	int tempi = 0;
	for (int i = 0; i < N; i++) {//分组
		if (temp == record[i].name)
			List[tempi].push_back(record[i]);
		else
		{
			tempi++;
			temp = record[i].name;
			List[tempi].push_back(record[i]);
		}
	}

	//for (int i = 0; i < r.size(); i++) {
	//	for (int j = 0; j < List[i].size(); j++)
	//		cout << List[i][j].name << " " << List[i][j].time << " " << List[i][j].state << endl;
	//}

	for (int i = 0; i < r.size(); i++) {
		TotalRate(List[i], rate);
	}


	

	return 0;
	

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值