PAT (Advanced Level) 1016 Phone Bills(恶心模拟)

mac2024-07-11  27

题目链接:点击查看

题目大意:模拟电话收费规则:

每个时间段的收费不同,时间段分为:00:00-01:00,01:00-02:00诸如此类最开始给出的单价是每分钟的单价

最后输出每个用户的电话费

题目分析:甲级的题目我就没读明白过,加上漏掉了好多细节,导致前期白费功夫:

题目保证给出相同的月份电话费为0的人不需要输出初始时给出的单价是美分,题目要求输出的答案是美元,100美分=1美元

再加上通过分析可以得到的,首先若可以组成配对,则排序后相邻两个的信息中,必须前者是on-line,后者是off-line,关于给出两个时间该怎么求花费,一开始我想推公式,O(1)得到答案,可是发现细枝末节太多了,根本顾不过来,最后还是屈服了,用了时间代价,枚举分钟来实现的,不得不说,暴力牛逼

一个是一开始没读懂题就直接上手做,导致做了很多无用功,还有一个就是能暴力就暴力,别想着乱七八糟的公式和规律了,暴力好理解还好实现,难道他不香吗?

挂代码吧,被恶心到了:

#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const int N=1e3+100; int cost[25]; int sum_cost=0;//所有的花费之和 unordered_map<string,bool>vis;//用来记录当前的人是否被访问过 struct date//记录时间 { int month; int day,hour,minute; bool operator<(const date& a)const { if(day!=a.day) return day<a.day; if(hour!=a.hour) return hour<a.hour; return minute<a.minute; } }; struct Node//记录每次通话信息 { string name; date time; bool state; bool operator<(const Node& a)const { if(name!=a.name)//先按姓名升序 return name<a.name; return time<a.time;//再按时间升序 } }a[N]; int get_sub(date st,date ed)//得到两次时间之差,返回分钟 { int ans1=st.day*24*60+st.hour*60+st.minute; int ans2=ed.day*24*60+ed.hour*60+ed.minute; return abs(ans1-ans2); } int cal(date st,date ed)//计算两次时间之间的花费,st<=ed { int d=st.day,h=st.hour,m=st.minute; int dd=ed.day,hh=ed.hour,mm=ed.minute; int ans=0; while(d<dd||h<hh||m<mm) { m++; ans+=cost[h]; if(m==60) { m=0; h++; } if(h==24) { h=0; d++; } } return ans; } int main() { // freopen("input.txt","r",stdin); for(int i=0;i<24;i++) { scanf("%d",cost+i); sum_cost+=cost[i]; } int n; scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>a[i].name; scanf("%d:%d:%d:%d",&a[i].time.month,&a[i].time.day,&a[i].time.hour,&a[i].time.minute); char ss[10]; scanf("%s",ss); if(ss[1]=='n') a[i].state=true; else a[i].state=false; } sort(a+1,a+1+n); int sum=0; for(int i=2;i<=n;i++) { if(a[i].name==a[i-1].name&&!a[i].state&&a[i-1].state)//同一个人,并且前一个是on,后一个是off { if(!vis[a[i-1].name])//如果没输出过,输出姓名 { printf("%s %02d\n",a[i-1].name.c_str(),a[i-1].time.month);//第一次打印姓名 vis[a[i-1].name]=true; } int money=cal(a[i-1].time,a[i].time); sum+=money; date st=a[i-1].time; date ed=a[i].time; printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n",st.day,st.hour,st.minute,ed.day,ed.hour,ed.minute,get_sub(st,ed),1.0*money/100); } if((i==n||a[i].name!=a[i+1].name)&&sum!=0)//sum为0时不必输出 { printf("Total amount: $%.2f\n",1.0*sum/100); sum=0; } } return 0; }

 

最新回复(0)