// CDVII (CDVII 高速公路)// PC/UVa IDs: 110406/10138, Popularity: C, Success rate: low Level: 2// Verdict: Accepted// Submission Date: 2011-05-23// UVa Run Time: 0.024s//// 著作權(C)2011,邱秋。metaphysis # yeah dot net//// 該題我 WA 了很多次,最後和別人獲得 AC 的程式比較才發現 UVa 和 Programming Challenges// 網站上的測試資料中表示車輛狀態的 enter 和 exit 竟然有字母為大寫的情況,完全不像題目所描述// 的,表示車輛狀態的為 ‘enter’ 和 ‘exit’,導致我判斷車輛是離開還是進入發生錯誤,浪費了很// 多時間。最後不得不把表示狀態的變數改成字串,通過判斷第二個字元是 ‘n’ 還是 ‘x’ 來判斷車輛// 是進入還是離開,才獲得 AC,應該把測試資料更正一下。#include <iostream>#include <sstream>#include <algorithm>#include <cstdlib>using namespace std;#define MAXSIZE 1000// 照片的最大數量。#define FARE_TYPES24// 時段收費的種類。#define ACCOUNT_FEE200// 月租費用,美分。#define TRIP_FEE100// 單次通過費用,美分。#ifndef DEBUG_MODE// #define DEBUG_MODE#endifstruct license_photo{string license;// 車輛牌照int time;// 進入時間,為:日 * 24 * 60 + 小時 * 60 + 分鐘。string status;// 車輛狀態:enter,exit。int location;// 距離高速公路一端的距離。int fare;// 收費標準,根據進入時間確定,美分。};#ifdef DEBUG_MODEostream & operator << (ostream &out, license_photo &photo){cout << photo.license << " " << photo.time << " ";cout << photo.status << " ";cout << photo.location << " " << photo.fare << endl;return out;}#endif// 如果牌照相同,記錄時間早的排在前面。bool cmp(license_photo x, license_photo y){if (x.license != y.license)return x.license < y.license;return x.time < y.time;}// 輸出一個賬單。void bill(string license, int fee){if (fee > 0){fee += ACCOUNT_FEE;cout.precision(2);cout.setf(ios::fixed | ios::showpoint);cout << license << " {1}quot; << (fee / 100.00) << endl;}}// 根據照片產生賬單列表。void bill_list(license_photo photos[], int capacity){// 對照片進行排序。sort(photos, photos + capacity, cmp);// 測試用。#ifdef DEBUG_MODEfor (int i = 0; i < capacity; i++)cout << "[" << i << "]" << photos[i];#endifint current = 0;while (current < capacity){// 當前計費的車輛牌照號碼。string license = photos[current].license;int fee = 0;bool entered = false;// 找到一輛車的進入/離開記錄對。不成對記錄忽略。for (; current < capacity && (photos[current].license == license); current++){// 找到一條進入記錄。if (!entered){if (photos[current].status[1] == 'n')entered = true;elsecontinue;}// 找到了進入記錄,找到一個離開記錄以成對。if (entered){if (photos[current].status[1] == 'x'){// 找到了配對記錄,根據收費標準計費。entered = false;fee += TRIP_FEE;fee += photos[current - 1].fare * abs(photos[current].location - photos[current - 1].location);// 測試用。#ifdef DEBUG_MODEcout << "<Debug Begin>" << endl;cout << "ENTER: " << (current - 1) << " " << photos[current - 1];cout << "EXIT: " << current << " " << photos[current];cout << "FEE: " << fee << endl;cout << "<Debug End>" << endl;#endif}elsecontinue;}}bill(license, fee);}}int main(int ac, char *av[]){int cases;license_photo photos[MAXSIZE];int toll[FARE_TYPES];string line;cin >> cases;while (cases--){for (int i = 0; i < FARE_TYPES; i++)cin >> toll[i];cin.ignore();int capacity = 0;while (getline(cin, line), line.length() > 0){istringstream iss(line);string date;// 牌照。iss >> photos[capacity].license >> date;// 記錄車輛進入和離開的相關資訊。photos[capacity].time = atoi(date.substr(3, 2).data()) * 24 * 60;photos[capacity].time += atoi(date.substr(6, 2).data()) * 60;photos[capacity].time += atoi(date.substr(9, 2).data());// 車輛狀態。iss >> photos[capacity].status >> photos[capacity].location;// 收費標準。photos[capacity].fare = toll[atoi(date.substr(6, 2).data())];capacity++;}bill_list(photos, capacity);// 無成對記錄的測試資料不輸出任何內容,僅輸出一個換行。需要注意。if (cases)cout << endl;}return 0;}