1016電話代(25分)
長距離電話会社は、次の規則により、顧客を充電します:
長距離電話をかけるコールが行われた日の時間に応じて、分あたり一定額の費用がかかります。顧客が長距離電話を接続し起動すると、時間が記録され、その電話アップ顧客ハング時間になります。すべての暦月は、法案は(一日の時間によって決定される速度で)と呼ばれる各分間顧客に送信されます。あなたの仕事は、携帯電話の通話記録のセットが指定されると、各月の請求書を準備することです。
入力仕様:
各入力ファイルは、1つ、彼は構造を評価、テストケース、および携帯電話の通話記録が含まれています。
そのため一日の各時間のために、午前2時 - 午前1時から午前1時、有料 - レート構造00:00から有料を示す24非負整数(セント/分)と線で構成され。
次の行はレコードのNラインに続く正の数N(≤1000)を含みます。各携帯電話の通話記録は、顧客(スペースなしで20文字までの文字列)の名前、日付と時刻(で構成mm:dd:hh:mm
)、および単語 on-line
や off-line
。
各テストケースの場合は、すべての日付は、単一ヶ月以内となります。各 on-line
レコードは、同じ顧客は、それが提供されるために時系列で次のレコードとペアになってい off-line
たレコード。どれ on-line
とペアにされていないレコードが off-line
あるとしてレコードは、無視される off-line
とペアになっていないレコードの on-line
レコードが。少なくとも1つの呼び出しがうまく入力にペアリングされていることを保証されています。あなたは、同じ顧客のための2つのレコードが同じ時間を持っていないと仮定してよいです。タイムズは、24時間クロックを使用して記録されています。
出力仕様:
各テストケースでは、各顧客の携帯電話の請求書を印刷する必要があります。
手形は、顧客名のアルファベット順に印刷されなければなりません。各顧客のために、最初の行に顧客の名前やサンプルが示す形式での法案の月を印刷します。その後、コールの各期間のために、1行で開始と終了時刻と日付を(印刷dd:hh:mm
)、持続時間(分単位)と呼び出しを担当。呼び出しは、年代順にリストされなければなりません。最後に、サンプルによって示された形式での月の総電荷を印刷します。
サンプル入力:
10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10
10
CYLL 01:01:06:01 on-line
CYLL 01:28:16:05 off-line
CYJJ 01:01:07:00 off-line
CYLL 01:01:08:03 off-line
CYJJ 01:01:05:59 on-line
aaa 01:01:01:03 on-line
aaa 01:02:00:01 on-line
CYLL 01:28:15:41 on-line
aaa 01:05:02:24 on-line
aaa 01:04:23:59 off-line
サンプル出力
CYJJ 01
01:05:59 01:07:00 61 $12.10
Total amount: $12.10
CYLL 01
01:06:01 01:08:03 122 $24.40
28:15:41 28:16:05 24 $3.85
Total amount: $28.25
aaa 01
02:00:01 04:23:59 4318 $638.80
Total amount: $638.80
まず、項目分析
次の規則に従って、長距離電話会社の料金は:通話に費やした時間に応じて、長距離通話は毎分の手数料がかかります。ユーザーが長距離通話を開始すると、時間が記録され、タイムアップユーザーハングが記録されますとき。毎月毎月の請求書には、(料金は一日の時間によって決定される)、ユーザに送信されます。あなたの仕事は、電話通話記録の毎月の請求書を準備することです。
情報を入力します。
- レート(24非負整数):0-1,1-2 ... 22-23,23-24
- レコード数(N≤1000):同じ月の各テストの各レコード、次の記録のためにオフラインに、記録がユーザーに任意のオンラインとオフラインの時系列記録とペアになっていませんが、オンラインで記録されています無視される、オンライン、オフライン、レコードとペアになっていない、無視されます。少なくとも一つの呼び出しの良いペアを入力してください。あなたは、同じ顧客のためノー2つのレコードが同じ時間をとることができます。24時間の録画時間を使用してください。
- ユーザー名:スペースなしで20の文字
- 日付と時刻:時間::月:日・ポイント
- 識別:オンライン/オフライン
出力:ユーザ名に基づいて辞書順
- 最初の行:
- ユーザー名
- 月の紙幣(出力フォーマットに従って、実施例)
- 次の数行:(年代順)
- (に応じて各通話開始時刻、終了時刻
dd:hh:mm的格式
)- (分単位で計算される)の合計継続時間
- 多くのお金を過ごすための呼び出し
- 出力形式に応じて最後の行:(実施例)
- 総コストのユーザーの月
第二に、問題解決のアイデア:
我々は、(次のオフラインレコードのユーザーのオンラインレコードに年代順に)各ユーザーのための効果的なコール情報を選出したいので、すべての入力レコードに最初の日付と時間に応じて、その後、ユーザー名辞書順にソート一致するレコードは、各ユーザのために選択された通話記録にソートした後;(日付、時間、分)ソート分の数、および消費量を算出する際にペアリング。
- ストレージ構造:
- レコードのユーザー名の保存、開始時刻、終了時刻、兆候:それは構造として記録されます
- 24時間間隔レート:アレイを記憶します
- ルールで入力します。
- CIN文字入力では不便で、特定のフォーマットを、時間がかかるので、ここでのscanfとprintf関数と(CIN COUTと好ましく混ぜません)
- 使用ストリングCHAR [] (示されていないのscanf型String)
- 並べ替え:
- ソート(REC、REC + N、CMP)。
- ルールを書き換えソート機能CMPを指定します
- 各レコードは、ユーザのペアリングを選択します:
- 有効な通話記録があるかどうかを決定します。でneedprint(= 0)記号として(= 1は、経験に基づいてオフ、上の検出された= 2であり、有効なユーザーの次の時間を記録していません)
- (この場合には、ユーザが[次、上の範囲を特定している))有効なレコードの一致するレコードをさらに発見があります:
(2.1)値がスケールで決定される。マッチは、特定のオンライン状態とオフラインの記録に応じて発見され
オフインデックス値を決定するステップ(2.2):+ OFF 1 = ON (範囲外、レコードがもうペアリングされていないオフの場合)
このペアリングレコードのコストの(2.3)の計算:開始時間プラス1が連続して有効期限が到来したか否かを判定し、各分費やした合計の料金(単位変換セント- > US; 2つの小数点以下の桁数)
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=1010;
int toll[25]; //每小时区间内:每分钟多少钱
//结构体
struct Record{
char name[25]; //姓名最多20个字符
int month,dd,hh,mm;
bool status; //true表示记录为online,否则为offline
}rec[maxn],temp;
//排序规则的制定
bool cmp(Record a,Record b){
int s=strcmp(a.name,b.name);
if(s!=0) //按名字字典顺序从小到大排序
return s<0;
else if(a.month!=b.month) //按月份从小到大排序
return a.month<b.month;
else if(a.dd!=b.dd) //按日期从小到大排序
return a.dd<b.dd;
else if(a.hh!=b.hh) //按小时从小到大排序
return a.hh<b.hh;
else //按分钟从小到大排序
return a.mm<b.mm;
}
void get_ans(int on,int off,int &time,int &money){
temp=rec[on];
while(temp.dd<rec[off].dd||temp.hh<rec[off].hh||temp.mm<rec[off].mm){ //不断将起始时间加1,判断是否到达终止时间
time++; //该次记录总时间加1min
money+=toll[temp.hh]; //按照本小时区间的费率相加
temp.mm++;
if(temp.mm>=60){
temp.mm=0;
temp.hh++;
}
if(temp.hh>=24){
temp.hh=0;
temp.dd++;
}
}
}
int main()
{
//数据的输入
for(int i=0;i<24;i++){ //24小时每小时区间的资费
scanf("%d",&toll[i]);
}
int n;
scanf("%d",&n); //记录数
char line[10]; //临时存放on-line和off-line的输入
for(int i=0;i<n;i++){ //n条记录的具体信息
scanf("%s",rec[i].name);
scanf("%d:%d:%d:%d",&rec[i].month,&rec[i].dd,&rec[i].hh,&rec[i].mm);
scanf("%s",line);
if(strcmp(line,"on-line")==0){
rec[i].status=true;
}else{
rec[i].status=false;
}
}
//所有记录按规则排序
sort(rec,rec+n,cmp);
//查找并输出配对记录
int on=0;
int off;
int next;
while(on<n){
//判断是否有配对、记录下一个用户编号next
int needprint=0;
next=on; //从当前位置开始寻找下一个用户
while(next<n&&strcmp(rec[next].name,rec[on].name)==0){
if(needprint==0&&rec[next].status==true){ //找到on
needprint=1;
}else if(needprint==1&&rec[next].status==false){ //找到on之后的第一个off
needprint=2;
}
next++; //不断递增,直到找到下一个用户
}
if(needprint<2){ //该用户没有匹配的记录on-off
on=next;
continue; //继续找下一个用户
}
int allmoney=0;
printf("%s %02d\n",rec[on].name,rec[on].month); //用户名和月份
while(on<next){
while(on<next-1&&!(rec[on].status==true&&rec[on+1].status==false)){
on++;
}
off=on+1;
if(off==next){ //所有配对已输出完毕,无配对
on=next;
break;
}
printf("%02d:%02d:%02d ",rec[on].dd,rec[on].hh,rec[on].mm);
printf("%02d:%02d:%02d ",rec[off].dd,rec[off].hh,rec[off].mm);
int time=0;
int money=0;
get_ans(on,off,time,money);
allmoney+=money;
printf("%d $%.2f\n",time,money/100.0);
on=off+1;
}
printf("Total amount: $%.2f\n",allmoney/100.0);
}
return 0;
}