浙大 PAT 甲级 1026 Table Tennis C++ 测试点说明 部分正确

思路

这题好难啊…尤其是测试点非常坑。我在牛客网上测试用例都通过了,但是在PAT上最后一个用例到现在也还没通过,不知道是哪里出了问题。

目前发现的坑点:

1、每个玩家占用时间不能超过两小时,超过两小时按两小时算。其实题目里没有明确地要求判断,但它既然都说了,那这么奇怪的一句话肯定是一个测点。应该是用例4。判断之后,用例4就通过了。

2、当有多个桌子空闲时,且空闲的里面有vip桌时,vip用户会选择编号最小的vip桌,即使有空闲的、编号更小的普通桌。如果空闲的里面没有vip桌,vip用户选择编号最小的桌。

3、等待时间四舍五入。round函数即可。

这两点考虑之后我就只剩下最后一个测点没法通过了。最后得分29/30,如果有大佬能帮忙看看我的代码哪里出错了,将不甚感激!!!

当然还有其他的一些问题,但是基本上会在给出的样例测点里体现出来,比如超过21点不服务等等,就不多说了。

我是这么考虑的,先记录所有人的信息和桌子的信息。

桌子维护三个数组,一个是vip[ ],记录该桌是否为vip桌,一个是table[ ],记录该桌即将空闲的时间,初始化为8*3600(早上八点),一个是number[ ],记录每桌服务人数。

人表示成Pair结构体,维护两个容器,一个是vector<Pair>pairs,记录所有人的信息,一个是queue<int>vpairs,记录vip用户在pairs中的下标。均按到达时间排序。

过程如下:

初始化各类信息。然后遍历已按到达时间排好序的vector<Pair> pairs。

如果是vip用户,调用findEarlyTableForVip函数,它是找到即将最早空闲/或者在该用户到达时处于空闲状态的所有(可能有多个)桌子中的vip桌,如果这批即将最早空闲/或者在该用户到达时处于空闲状态的桌子里没有vip桌,则返回0,否则返回编号最小的那张空闲的vip桌子编号。回到主函数,判断如果findEarlyTableForVip不为0,则将返回值的桌子编号分配给这个vip用户,更新各类信息。如果为0,则调用findEarlyTable函数,这个函数就是找到即将最早空闲/或者在该用户到达时处于空闲状态的编号最小的桌子,不管它是普通桌还是vip桌。那么这个函数的返回值的桌子编号就分配给这个vip用户(这个vip用户在当前没有空闲vip桌的情况下坐上了普通桌),更新各类信息。

如果是普通用户,调用findEarlyTableForCommon函数,这个函数是为普通用户分配桌子的,返回最合适的桌子。这个函数的主体是一个循环,先看看vpairs(记录了vip用户在pairs中的下标,是按到达时间排序的,如果最前面的vip用户已分配,则pop,所以它的队头永远是下一个待分配的vip用户)是否为空,如果为空,代表没有vip用户了,普通用户可以为所欲为,直接调用findEarlyTable函数找到最合适的桌子,返回,然后回到主函数更新各类信息。如果不为空,那么在为这个普通用户分配桌子前,要照顾vip用户,调用findEarlyTableForVip,如果发现有空闲的vip桌并且当前第一个vip的到达时间是早于这个vip桌的,那么为这个vip分配(记得给这个vip打一个标记,因为后面再处理到它时就要跳过),并且更新各类信息。然后continue,直到没有符合条件的vip,这时就再调用findEarlyTable为这个普通用户找张桌子,返回,回到了主函数更新各类信息。

程序还维护了一个vector<int> servingSquence,每当为一个用户分配桌子,并且分配时间在21:00以前,那么将它的下标push进去。最后按照这个vector里的顺序打印结果即可。

牛客网上的这题测点都过了,但是PAT的最后一个测点过不了,不知道为啥…反复想了很多遍,也不知道哪里有漏洞。后来我按照别人的方法仿写过,过了,但是我自己写的代码却总有一个测点过不了,而且想不出原因,这让人寝食难安啊啊。希望有大佬可以帮助我。

#include<stdio.h>
#include<vector>
#include<queue>
#include<math.h>
#include<algorithm>

using namespace std;

struct Pair
{
    int arr;
    int ser;
    int duration;
    int tag;
};

bool vip[101];
int number[101];
int table[101];

vector<Pair> pairs;
queue<int> vpairs;
vector<int> servingSquence;

bool cmp(Pair p1, Pair p2)
{
    return (p1.arr < p2.arr);
}

void init()
{
    for (int i = 0; i < 101; i++)
    {
        vip[i] = false;
        number[i] = 0;
        table[i] = 8 * 3600;
    }
}
int findEarlyTableForVip(int K, int arr)
{
    vector<int> candidate;
    int ans = 1000000;
    for (int i = 1; i <= K; i++)
    {
        if (table[i] <= arr)
        {
            if (ans > arr)
            {
                candidate.clear();
            }
            ans = -1;
            candidate.push_back(i);
        }
        if (table[i] < ans)
        {
            candidate.clear();
            candidate.push_back(i);
            ans = table[i];
        }
        else if (table[i] == ans)
        {
            candidate.push_back(i);
        }
    }
    for (int i = 0; i < candidate.size(); i++)
    {
        if (vip[candidate[i]] == true)
        {
            return candidate[i];
        }
    }
    return 0;
}

int findEarlyTable(int K, int arr)
{
    int res = 0;
    int ans = 1000000;
    for (int i = 1; i <= K; i++)
    {
        if (table[i] <= arr)
        {
            res = i;
            break;
        }
        if (table[i] < ans)
        {
            ans = table[i];
            res = i;
        }
    }
    return res;
}

int findEarlyTableForCommon(int K, int arr)
{
    while (1)
    {
        if (vpairs.empty() == true)
        {
            return findEarlyTable(K, arr);
        }
        else
        {
            int candidate = findEarlyTableForVip(K, arr);
            if (candidate != 0 && pairs[vpairs.front()].arr <= table[candidate])
            {
                int tmp = vpairs.front();
                pairs[tmp].tag = -1;
                pairs[tmp].ser = table[candidate];
                vpairs.pop();
                if (pairs[tmp].ser < 21 * 3600)
                {
                    number[candidate]++;
                    servingSquence.push_back(tmp);
                }
                table[candidate] += pairs[tmp].duration;
                continue;
            }
        }
        return findEarlyTable(K, arr);
    }
}

int main()
{
    int N;
    scanf("%d", &N);

    for (int i = 0; i < N; i++)
    {
        int h, m, s;
        Pair p;
        scanf("%d:%d:%d %d %d", &h, &m, &s, &p.duration, &p.tag);
        // 用例4
        if (p.duration > 120)
        {
            p.duration = 120;
        }
        p.duration *= 60;
        p.arr = h * 3600 + m * 60 + s;
        pairs.push_back(p);
    }
    sort(pairs.begin(), pairs.end(), cmp);
    for (int i = 0; i < N; i++)
    {
        if (pairs[i].tag == 1)
        {
            vpairs.push(i);
        }
    }
    int K, M;
    scanf("%d%d", &K, &M);
    for (int i = 1; i <= M; i++)
    {
        int t;
        scanf("%d", &t);
        vip[t] = true;
    }
    for (int i = 0; i < N; i++)
    {
        if (pairs[i].tag == -1)
        {
            continue;
        }
        if (pairs[i].tag == 1)
        {
            int bestTable = findEarlyTableForVip(K, pairs[i].arr);
            if (bestTable == 0)
            {
                bestTable = findEarlyTable(K, pairs[i].arr);
            }
            pairs[i].ser = (pairs[i].arr < table[bestTable]) ? table[bestTable] : pairs[i].arr;
            if (pairs[i].ser < 21 * 3600)
            {
                number[bestTable]++;
                servingSquence.push_back(i);
            }
            table[bestTable] = pairs[i].ser + pairs[i].duration;
            vpairs.pop();
        }
        else
        {
            int bestTable = findEarlyTableForCommon(K, pairs[i].arr);
            pairs[i].ser = (pairs[i].arr < table[bestTable]) ? table[bestTable] : pairs[i].arr;
            if (pairs[i].ser < 21 * 3600)
            {
                number[bestTable]++;
                servingSquence.push_back(i);
            }
            table[bestTable] = pairs[i].ser + pairs[i].duration;
        }
    }
    for (int j = 0; j < servingSquence.size(); j++)
    {
        int i = servingSquence[j];
        if (pairs[i].ser >= 21 * 3600)
        {
            continue;
        }
        else
        {
            int arrive = pairs[i].arr;
            int serve = pairs[i].ser;
            int wait = round(float(pairs[i].ser - pairs[i].arr) / 60.0);
            printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",
                arrive / 3600, (arrive % 3600) / 60, arrive % 3600 % 60,
                serve / 3600, (serve % 3600) / 60, serve % 3600 % 60, wait);
        }
    }
    for (int i = 1; i <= K; i++)
    {
        if (i == 1)
        {
            printf("%d", number[i]);
            continue;
        }
        printf(" %d", number[i]);
    }
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值