d089: 00145 - Gondwanaland Telecom

  1. 1. 內容
  2. 2. 範例輸入
  3. 3. 範例輸出
  4. 4. 想法
  5. 5. 程式碼

CPE 一顆星

題目連結:https://zerojudge.tw/ShowProblem?problemid=d089

內容

Gondwanaland Telecom這家電話公司收費的標準是以所撥電話的距離及時段來訂定的,如下表。在這裡charging step就是指不同的距離。

Charging Step Day Rate Evening Rate Night Rate
A 0.10 0.06 0.02
B 0.25 0.15 0.05
C 0.53 0.33 0.13
D 0.87 0.47 0.17
E 1.44 0.80 0.30

Day Rate = 8am to 6pm
Evening Rate = 6pm to 10pm
Night Rate = 10pm to 8am

所有的收費是根據該通電話每一分鐘多少錢來計算的,所以若有某通電話有跨時段,則按時段不同的收費標準分別計算在加總。例如:有一通電話從5:58pm開始到6:04pm結束,那前2分鐘是按白天(Day)的標準計費,而後4分鐘則按傍晚(Evening)的標準計費。

所有小於一分鐘的電話不列入計費,而且沒有一通電話會持續超過24小時。

每筆測資一列,分別代表 charging step(A~Z)、電話號碼、開始時間、結束時間。
輸入 # 代表結束。

輸出電話號碼、各時段通話分鐘數、charging step、總花費。
各部分輸出於一定位置,以靠右對齊來說,分別在10,16,22,28,31,39的位置。

範例輸入

C 765-7457 10 41 04 29
B 207-0225 21 28 07 53
B 316-0414 16 43 09 37
C 463-1401 19 28 00 33
D 514-9373 01 20 09 08
#

範例輸出

765-7457 439 240 389 C 362.44
207-0225 0 32 593 B 34.45
316-0414 174 240 600 B 109.50
463-1401 0 152 153 C 70.05
514-9373 68 0 400 D 127.16

想法

先將計費表用 map 儲存,並把時間分成如下7個部分,把每一部分的結束時間以陣列儲存。
0:00 ~ 8:00
8:00 ~ 18:00
18:00 ~ 22:00
22:00 ~ 8:00 (隔天)
8:00 ~ 18:00
18:00 ~ 22:00
22:00 ~ 24:00

將時間轉換成分鐘方便計算,若通話結束時間小於通話開始時間,則代表跨夜,需將其加上24小時(若兩者相等以通話24小時計算,不然UVA會WA)。

另開一陣列紀錄各個時間區間的通話分鐘數,接著就可以開始遍歷剛剛建立的儲存各個結束時間的陣列,判斷通話開始時間是否與結束時間在同一區間,若否,則紀錄此區間通話分鐘數,並更新通話開始時間為此區間結束時間。過程中可順便計算花費(通話分鐘數*計費表對應的價錢)。

最後將各區間通話分鐘數依照 Day, Evening, Night 區分即可。

輸出時可用 setw() 調整對齊。

參考資料:YUI HUANG 演算法學習筆記

程式碼

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(false), cin.tie(nullptr)
using namespace std;

int main(){
fastio;
map<char, vector<double>> mp;
mp['A'] = {0.02, 0.10, 0.06, 0.02, 0.10, 0.06, 0.02};
mp['B'] = {0.05, 0.25, 0.15, 0.05, 0.25, 0.15, 0.05};
mp['C'] = {0.13, 0.53, 0.33, 0.13, 0.53, 0.33, 0.13};
mp['D'] = {0.17, 0.87, 0.47, 0.17, 0.87, 0.47, 0.17};
mp['E'] = {0.30, 1.44, 0.80, 0.30, 1.44, 0.80, 0.30};
int time[] = {480, 1080, 1320, 1920, 2520, 2760, 2880};
char step;
string phone_number;
int hour1, min1, hour2, min2, sum1, sum2, Day, Evening, Night;
double cost[7], total;
while(cin >> step){
if(step == '#') break;
memset(cost, 0, sizeof(cost));
cin >> phone_number >> hour1 >> min1 >> hour2 >> min2;
sum1 = hour1*60 + min1, sum2 = hour2*60 + min2;
if(sum1 >= sum2) sum2 += 24*60;
Day = Evening = Night = total = 0;
for(int i = 0; i < 7; ++i){
if(sum1 <= time[i]){
if(sum2 <= time[i]){
cost[i] = sum2 - sum1;
total += cost[i] * mp[step][i];
break;
}
else {
cost[i] = time[i] - sum1;
total += cost[i] * mp[step][i];
sum1 = time[i];
}
}
}
Day = cost[1] + cost[4];
Evening = cost[2] + cost[5];
Night = cost[0] + cost[3] + cost[6];
cout << setw(10) << phone_number;
cout << setw(6) << Day << setw(6) << Evening << setw(6) << Night << setw(3) << step;
cout << setw(8) << fixed << setprecision(2) << total << "\n";
}
return 0;
}