PAT A1016
本質上是一個很簡單的問題,但是在寫程式碼實現上發現自己還是一個弱雞;
主要的思路就是先進行記錄的錄入和排序,按照字典序、時間大小進行排序,使得同一個人的記錄在一起,並且按照日期遞增;
後續難就難在怎麼進行on-line和off-line狀態的查詢以及計費的計算;
對於狀態查詢,示例程式碼有如下操作:
1.先進行同一人記錄的查詢,找到最後一條的邊界,並且在尋找邊界的時候,查詢是否有online和offline的匹配,如果沒有,則說明這個人通話沒必要計費;
2.如果有配對的狀態,從開始的邊界到最後邊界進行依次兩個兩個列舉,如果兩個狀態匹配,則進行計費的計算;
對於計費計算來說,最根本的難點是怎麼計算時長,以及對不同小時的費用進行計費;
示例程式碼給了一個很好的思路,那就是對於起始時間,進行重複的分鐘+1列舉,並且進行時間進位制計算,直到和結束時間相同;由於題目中時按分鐘計費的,所以只需要關注遞增的起始時間的小時變化即可;
這段程式碼如下所示:
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){ time++; money+=toll[temp.hh]; temp.mm++; if(temp.mm>=60){ temp.mm=0; temp.hh++; } if(temp.hh>=24){ temp.hh=0; temp.dd++; } } }
總體的程式碼如下所示:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1010; int toll[25]; struct Record{ char name[25]; int month,dd,hh,mm; bool status; }rec[maxn],temp; 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){ time++; money+=toll[temp.hh]; temp.mm++; if(temp.mm>=60){ temp.mm=0; temp.hh++; } if(temp.hh>=24){ temp.hh=0; temp.dd++; } } } 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; } int main(){ for(int i=0;i<24;i++){ scanf("%d",&toll[i]); } int n; scanf("%d",&n); char line[10]; for(int i=0;i<n;i++){ 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,off,next; while(on<n){ int needPrint=0; next=on; while(next<n&&strcmp(rec[next].name,rec[on].name)==0){ if(needPrint==0&&rec[next].status==true){ needPrint=1; }else if(needPrint==1&&rec[next].status==false){ needPrint=2; } next++; } if(needPrint<2){ 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,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); } system("pause"); return 0; }