zoukankan      html  css  js  c++  java
  • PAT 1017. Queueing at Bank (25)

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<iomanip>
    #include<algorithm>
    using namespace std;
    
    const int MAX_N = 10000+5;
    const int MAX_WIN = 100+5;
    const int OFF_TIME = 9*60*60;
    const int ONE_HOUR = 60*60;
    
    struct Customer
    {
    	int iArrTime;  //到达的时间
    	int iProTime;  //处理的时间
    	int iWaitTime; //等待的时间
    	bool isServed;//是否被处理
    };
    Customer arrCus[MAX_N];
    
    struct Windows
    {
    	int iAvaiTime;//窗口available的时间
    	
    };
    Windows arrWins[MAX_WIN];
    
    //按到达时间进行排序
    bool lessCmp(Customer cus1, Customer cus2)
    {
    	return cus1.iArrTime < cus2.iArrTime;
    }
    
    //将07:55:00形式的时间转换为相对08:00的时间,单位:秒。
    //如果早于8点,则返回负数。
    int getRelTime(char *chTime)
    {
    	int iRes;
    	int h = (chTime[0] - '0')*10 + chTime[1]-'0';
    	int m = (chTime[3] - '0')*10 + chTime[4]-'0';
    	int s = (chTime[6] - '0')*10 + chTime[7]-'0';
    	int iEight = 8*60*60;
    	int iNow = (h*60 + m)*60 + s;
    	iRes = iNow - iEight;
    	return iRes;
    }
    
    void initData(int N,int K)
    {
    	int i,j;
    	for(i=0; i<N; i++)
    	{
    		arrCus[i].iArrTime = 0;
    		arrCus[i].iProTime = 0;
    		arrCus[i].iWaitTime = 0;
    		arrCus[i].isServed = true;
    	}
    	for(j=0; j<K; j++)
    	{
    		arrWins[j].iAvaiTime = 0;		
    	}
    }
    
    
    //得到一个空闲的窗口,遍历K个窗口,找到窗口available最早的时间
    int getAnFreeWin(int K)
    {
    	int iAvaTimeMin = arrWins[0].iAvaiTime;
    	int iWinIndex = 0;
    	for(int i=1; i<K; i++)
    		if(arrWins[i].iAvaiTime < iAvaTimeMin)
    		{
    			iAvaTimeMin = arrWins[i].iAvaiTime;
    			iWinIndex = i;
    		}
    	return iWinIndex;
    }
    
    int max(int a,int b)
    {
    	return a>b?a:b;
    }
    
    //窗口iWinId处理完一个客户后,需要更新窗口available最早的时间
    void updateWinsInfo(int iWinId,int iCusId)
    {
    	int iCurTime = max(arrWins[iWinId].iAvaiTime,arrCus[iCusId].iArrTime);
    
    	if(arrCus[iCusId].iProTime <= ONE_HOUR)//处理的时间不能超过一个小时
    		arrWins[iWinId].iAvaiTime =iCurTime + arrCus[iCusId].iProTime;
    	else
    		arrWins[iWinId].iAvaiTime =iCurTime + ONE_HOUR;
    }
    
    //将iCusId客户放到窗口iWinId进行处理
    void processAnCus(int iWinId, int iCusId)
    {
    	//如果在客户到之前就有窗口空闲,或者在下班以后窗口才空闲,则等待时间为0
    
    	if(arrWins[iWinId].iAvaiTime == 0) //开始就空闲的窗口
    	{
    		if(arrCus[iCusId].iArrTime < 0)
    			arrCus[iCusId].iWaitTime = abs(arrCus[iCusId].iArrTime);
    		else if(arrCus[iCusId].iArrTime > OFF_TIME)
    		{
    			arrCus[iCusId].iWaitTime = 0;
    			arrCus[iCusId].isServed = false;
    		}
    		else //没有等待,直接到窗口。
    			arrCus[iCusId].iWaitTime = 0;
    	}
    	else//处理过客户的窗口
    	{
    		//if(arrWins[iWinId].iAvaiTime > OFF_TIME || arrCus[iCusId].iArrTime > OFF_TIME)//下班后的将不被处理
                    if(arrCus[iCusId].iArrTime > OFF_TIME)//之前一直有个case过不了,发现是题目意思理解错了。。
                    //即,客户只要在17:00之前到达银行,那么即使窗口的avaliable时间在17:00以后,那银行还是需要给
                    //客户进行服务的
    		{
    			arrCus[iCusId].iWaitTime = 0;
    			arrCus[iCusId].isServed = false;
    		}
    		else
    		{
    			if(arrWins[iWinId].iAvaiTime <= arrCus[iCusId].iArrTime)
    				arrCus[iCusId].iWaitTime = 0;
    			else
    				arrCus[iCusId].iWaitTime = arrWins[iWinId].iAvaiTime - arrCus[iCusId].iArrTime;
    		}
    	}
    		
    	updateWinsInfo(iWinId,iCusId);
    }
    
    //获得所有客户的等待时间
    double getAverageWaitTime(int N)
    {
    	int iSum = 0;
    	int iCount = 0;
    	for(int i=0; i<N; i++)
    		if(arrCus[i].isServed)
    		{
    			iSum += arrCus[i].iWaitTime;
    			iCount++;
    		}
    	if(iCount == 0)
    		return 0;
    	else
    		return (double(iSum)/60)/iCount;
    }
    
    //对在等待队列上的客户进行处理
    void process(int N, int K)
    {
    	sort(arrCus,arrCus+N,lessCmp);
    	int iCusId = 0;
    	while(iCusId < N)
    	{
    		int iFreeWinId = getAnFreeWin(K);
    		processAnCus(iFreeWinId, iCusId);
    		iCusId++;
    	}
    }
    
    int main()
    {	
    	int N,K,i,j,iProTime;
    	char chArrTime[10];
    	scanf("%d %d",&N,&K);
    	initData(N,K);
    	for(i=0; i<N; i++)
    	{
    		scanf("%s",chArrTime);
    		int iRelTime = getRelTime(chArrTime);
    		arrCus[i].iArrTime = iRelTime;
    		scanf("%d",&iProTime);
    		arrCus[i].iProTime = iProTime*60;
    	}
    	process(N, K);
    	cout<<fixed<<setprecision(1)<<getAverageWaitTime(N)<<endl;
    	return 0;
    }
    

      

    多学习,多总结。
  • 相关阅读:
    LightOJ 1245(Harmonic Number (II))
    牛客练习赛13 乌龟跑步(DP)
    vue-cli 打包编译 -webkit-box-orient: vertical 被删除解决办法
    vue静态文件处理
    vue项目关闭eslint检查
    Mac 桌面软件开发基础问答
    Mac App开发
    mac os app 开发
    vue中html模板使用绑定的全局函数
    软件版本标识
  • 原文地址:https://www.cnblogs.com/yanhaiming/p/2813385.html
Copyright © 2011-2022 走看看