PAT 1016 Phone Bills 簡單易懂 C++

 

1016 Phone Bills

題目連接: https://pintia.cn/problem-sets/994805342720868352/problems/994805493648703488

代碼簡單易懂. 覺得算法筆記書上的代碼過於複雜了.

想法是:

迭代Cus數組,

首先, getcusindex函數 根據起始位置, 找出同一用戶的起始位置和終止位置

然後, makesurevalid函數  找到該用戶至少要有一個配對的on-line & off-line, 找到後, 就可以把起始位置定位到該用戶第一個有效的on-line, 便於後續計算

最後, printbill函數用來打印賬單, 其間調用money函數, money函數對於給定的一個有效的on-line, off-line, 求出該段的時間, 和消費的錢, 返回給printbill打印.

打印完後, 將起始位置更新爲下一用戶的起始位置

判斷起始位置條件是否有效, 循環.

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <cstring>
struct Cus{
  char name[21];
  int month;
  int day;
  int hour;
  int min;
  int state;    //on-line=1, off-line=0;
};

double hours[24];

bool cmp(Cus a, Cus b){
    if(strcmp(a.name,b.name)!=0) return strcmp(a.name, b.name)<0;
    else if(a.month!=b.month) return a.month<b.month;
    else if(a.day!=b.day) return a.day<b.day;
    else if(a.hour!=b.hour) return a.hour<b.hour;
    else return a.min<b.min;

}
double money(Cus a, Cus b, int *mins){
  int aday = a.day;
  int ahour = a.hour;
  int amin = a.min;
  int bday = b.day;
  int bhour = b.hour;
  int bmin = b.min;
  double temp = 0.00;
  while(aday!=bday || amin!=bmin || ahour!=bhour){
        temp+=hours[ahour];
        amin++; (*mins)++;
        if(amin==60){
            ahour++; amin=0; 
        }
        if(ahour==24){
            aday++; ahour=0;
        }
  }
  return temp;
}
void getcusindex(Cus *cus, int* start, int* end, int n){
  for(int i=*start; i<n-1; ++i){
    if(strcmp(cus[i].name, cus[i+1].name)!=0){
        *end = i;
        return ;
    }
    *end = n-1;
  }
}
bool makesurevalid(Cus *cus, int* start, int* end){
    for(int i=*start; i<*end; ++i){
        if(cus[i].state-cus[i+1].state==1){
            *start = i;
            return true;
        }
    }
    return false;
}
void printbill(Cus *cus, int* start, int*end){
  double total=0.0;
  printf("%s %02d\n", cus[*start].name, cus[*start].month);  
  for(int i=*start; i<*end; ++i){
        if(cus[i].state-cus[i+1].state==1){
          int mins=0;
          double temp = money(cus[i], cus[i+1], &mins);   
          printf("%02d:%02d:%02d %02d:%02d:%02d %d $%.2f\n", cus[i].day, cus[i].hour, cus[i].min, cus[i+1].day, cus[i+1].hour, cus[i+1].min, mins, temp);
          total += temp;
        }
  }
  printf("Total amount: $%.2f\n", total);
}
int main(){
  for(int i=0; i<24; ++i){
    int temp;
    scanf("%d", &temp);
    hours[i] = (double)temp/100;
  }
  int n;
  scanf("%d", &n);
  if(n==0||n==1) return 0;
  struct Cus cus[n];
  char statetemp[10];
  for(int i=0; i<n; ++i){
    scanf("%s %d:%d:%d:%d %s",cus[i].name, &cus[i].month, &cus[i].day, &cus[i].hour, &cus[i].min, statetemp);
    if(strcmp(statetemp,"on-line")) cus[i].state=0; else cus[i].state=1;
  }
  std::sort(cus, cus+n, cmp);
/*
  for(int i=0; i<n; ++i){
    printf("%02d: %s %02d:%02d:%02d:%02d %d\n", i, cus[i].name, cus[i].month, cus[i].day, cus[i].hour, cus[i].min, cus[i].state);
  }
  */
  int cusstart=0;
  int cusend=0;
  int cusindex=0;
  do{
    getcusindex(cus, &cusstart, &cusend, n);
    if(makesurevalid(cus, &cusstart, &cusend)){
        printbill(cus, &cusstart, &cusend);
    }
    cusstart = cusend + 1;
  }while(cusstart<n-1);
  return 0;
}

附上算法筆記源代碼:

#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;
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 getans(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++;
		}
	}
}  
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;
			getans(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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章