(自用随笔)PAT A1017 Queueing at Bank

第一个思路就是模拟,每次模拟时间加一秒。但写出来发现太麻烦了。细节太多,结果错了也找不到错误的地方。。。。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <queue>

using namespace std;

struct Custom
{
    int h,m,s;
    int t;
    bool isActive;
};
Custom *custom;

int N,W,num;
vector<Custom> c;
vector<Custom>::iterator it;
int wait;
Custom time;
int window_num;

bool cmp(Custom c1,Custom c2)
{
    if(c1.h == c2.h)
    {
        if(c1.m == c2.m)
        {
            return c1.s < c2.s;
        }
        return c1.m < c2.m;
    }
    return c1.h < c2.h;
}

void InsertCustomer()
{
    if(time.h == custom[num].h && time.m == custom[num].m && time.s == custom[num].s)
    {
        c.push_back(custom[num]);

        num++;
        return;
    }
    return;
}

void Action()
{
    while(!c.empty() || num<N)
    {
        //运转时间
        time.s++;
        if(time.s == 60)
        {
            time.s = 0;
            time.m++;
            if(time.m == 60)
            {
                time.m = 0;
                time.h++;
            }
        }

        //8点前一直等待
        if(time.h<8 || (time.h==8 && time.m ==0 && time.s==0))
        {
            if(num<N)
            {
                InsertCustomer();
                wait--;
            }

            for(it = c.begin(); it != c.end(); it++)
            {
                if(!((*it).isActive))
                {
                    wait++;
                }
            }
            continue;
        }
        //8点以后视窗口情况
        if(window_num == 0)
        {
            if(num<N)
            {
                InsertCustomer();
            }
            for(it = c.begin(); it != c.end(); it++)
            {
                if(!((*it).isActive))
                {
                    wait++;
                }else
                {
                    (*it).t--;
                    if((*it).t == 0)
                    {
                        c.erase(it);
                        printf("%d %d %d\n",time.h,time.m,time.s);
                        it--;
                        window_num++;
                    }
                }
            }
        }
        else
        {
            if(num<N)
            {
                InsertCustomer();
            }
            for(it = c.begin(); it != c.end(); it++)
            {
                if((*it).isActive)
                {
                    (*it).t--;
                    if((*it).t == 0)
                    {
                        c.erase(it);
                        it--;
                        window_num++;
                    }
                }else
                {
                    (*it).isActive = true;
                    (*it).t--;
                    window_num--;
                }
            }
        }
    }
}

int main()
{
    int tempN;
    scanf("%d %d",&tempN,&W);
    N = tempN;
    custom = new Custom[N];
    window_num = W;
    num = 1; //从第二个顾客开始对比时间
    for(int i = 0;i<tempN;i++)
    {
        scanf("%d:%d:%d %d",&custom[i].h,&custom[i].m,&custom[i].s,&custom[i].t);
        custom[i].t *= 60;
        if(custom[i].h >=17)
        {
            N--;
        }
    }

    sort(custom,custom+tempN,cmp);
    time.h = custom[0].h;
    time.m = custom[0].m;
    time.s = custom[0].s;
    c.push_back(custom[0]);
    Action();

    float ave = 0;
    ave = (wait/tempN)/60.0;
    printf("%.1f",ave);

    return 0;
}

写的过程中遇到的知识疏漏:vector的iterator迭代器,只能用it != c.end() 判断是否到结尾,不能用it < c.end()。

且在迭代过程中调用了erase函数的话,需要立刻把迭代器指针-1,因为erase返回的指针就是指向被擦除的元素的下一个,循环体继续执行后,it会自动+1。

一个数学表达式在计算时,结果返回为最精确的类型(如int*float,结果为float)。

 

正确代码如下:

#include<iostream>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<iterator>
#include<algorithm>
#include<cstring>
using namespace std;
int gettick(int h,int m,int s)
{
    return h*60*60+m*60+s;
}
const int window_starttime = gettick(8,0,0);
const int window_endtime = gettick(17,0,0);
struct Customer
{
    int cometime;   //来到时间
    int protime;    //处理时间,秒
};
int getfreewindow(int* windows,int k)
{
    int mintime = windows[0],mink = 0;
    for(int i=1;i<k;++i)
    {
        if(mintime > windows[i])
        {
            mink = i;
            mintime = windows[i];
        }
    }
    //注释1:该种情况就是,这个人是17点之前来的,但是前面有人结束后就已经是17点以后了,这种情况也不需要过滤,还是计算在内的。
    //if(mintime>window_endtime) return -1;
    return mink;
}
int cmp(const Customer& c1,const Customer& c2)
{
    return c1.cometime < c2.cometime;
}

int main()
{
    #ifdef ONLINE_JUDGE
    #else
        freopen("test.txt","r",stdin);
    #endif
    int n,k;
    scanf("%d%d",&n,&k);
    vector<Customer> vcus;
    for(int i=0;i<n;++i)
    {
        int h,m,s,p;
        scanf("%d:%d:%d%d",&h,&m,&s,&p);
        Customer cus;
        cus.cometime = gettick(h,m,s);
        cus.protime = min(60*p,60*60);
        if(cus.cometime <= window_endtime)      //过滤17点以后来的人
            vcus.push_back(cus);
    }
    n = vcus.size();
    sort(vcus.begin(),vcus.end(),cmp);
    int twaittime = 0/*总等待时间*/,cnt=0/*得到处理的人数*/,windowstime[k]/*该窗口空闲时间*/;
    for(int i=0;i<k;++i)
        windowstime[i] = window_starttime;
    for(int i=0;i<n;++i)
    {
        int iw = getfreewindow(windowstime,k);
        if(iw==-1) break;
        ++cnt;
        Customer &cus = vcus[i];
        if(cus.cometime<windowstime[iw])
        {
            twaittime+= (windowstime[iw]-cus.cometime);
            windowstime[iw] += cus.protime;
        }
        else
        {
            windowstime[iw] = cus.cometime + cus.protime;
        }
    }
    if(cnt==0) printf("0.0\n");
    else printf("%.1lf\n",1.0f*twaittime/cnt/60);
    return 0;
}

(正确代码参考https://www.cnblogs.com/jlyg/p/7525244.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值