| 時段 | 車型 | 首小時 (每15分) | 首小時後 (每15分) |
|---|---|---|---|
| 白天 07:00-21:00 | 小型車 | 2.5 元 | 3.75 元 |
| 大型車 | 5 元 | 7.5 元 | |
| 夜間 21:00-07:00 | 小型車 | 每 2 小時 1 元 (不足按 2 小時算) | |
| 大型車 | 每 2 小時 2 元 (不足按 2 小時算) | ||
白天不足 15 分鐘按 15 分鐘計;夜間不足 2 小時按 2 小時計。跨時段需分段計費。
const int PER_TIME = 15; // 分鐘
const float SMALL_DAY_FIRST = 2.5f, SMALL_DAY_AFTER = 3.75f;
const float BIG_DAY_FIRST = 5.0f, BIG_DAY_AFTER = 7.5f;
const int SMALL_NIGHT_2H = 1, BIG_NIGHT_2H = 2; // 每2小時費用
// 時間拆解結構
typedef struct { int y, m, d, h, min; } DateTime;
Compare(start, end):判斷起止時間先後。GenerateMonth(year):含閏年判斷的月天數表。
// 判斷給定小時是否屬於夜間
bool IsNightHour(int hour) {
return hour >= 21 || hour < 7;
}
採用時間步進法:從開始時間按最小計費單位 (白天 15分 / 夜間 2小時) 遞增,累加費用,直到達到結束時間。
double CalculateFee(DateTime start, DateTime end, int carType) {
double total = 0;
DateTime cur = start;
while (Compare(cur, end)) { // cur < end
bool night = IsNightHour(cur.h);
int stepMin = night ? 120 : PER_TIME; // 夜間2小時=120分,白天15分
float rate = 0;
if (night) {
rate = (carType == 1) ? SMALL_NIGHT_2H : BIG_NIGHT_2H;
total += rate; // 每步直接加費用
} else {
// 白天需區分首小時
static int dayMinutesUsed = 0; // 簡化:實際需跨天重置
// 這裡簡化演示,完整版需精確追蹤首小時邊界
rate = (dayMinutesUsed < 60) ?
(carType==1?SMALL_DAY_FIRST:BIG_DAY_FIRST) :
(carType==1?SMALL_DAY_AFTER:BIG_DAY_AFTER);
total += rate;
dayMinutesUsed += stepMin;
}
// 時間前進 stepMin 分鐘
cur.min += stepMin;
NormalizeTime(&cur); // 處理分≥60、時≥24等進位
}
return total;
}
int main() {
DateTime start, end;
int carType;
printf("Enter start (y m d h min): "); scanf("%d%d%d%d%d", &start.y,&start.m,&start.d,&start.h,&start.min);
printf("Car type (1 small, 2 big): "); scanf("%d", &carType);
printf("Enter end (y m d h min): "); scanf("%d%d%d%d%d", &end.y,&end.m,&end.d,&end.h,&end.min);
if (!Compare(start, end)) { printf("Time error\n"); return 1; }
double fee = CalculateFee(start, end, carType);
printf("Total parking fee: %.2f\n", fee);
return 0;
}
StatisticsTime 中,難以維護。time_t 時間戳 + localtime 轉換,以秒為單位精確計算時長,再按規則分段定價,邏輯更清晰、不易出錯。複雜計費系統關鍵在於將時間離散化為最小計費單位,並狀態化首小時/夜間標識,避免在巨大循環中硬編碼邊界條件。