PAT(甲级)1026

昨天花了4h写代码,没想到一开始就没走对路,写了半天还是。。。
一看网友的,惊觉,oh!天!网友实在是太聪明了。
用了两个队列,一个是普通用户队列,一个是VIP用户队列。
参考了几个博主的,研究了下,终于明白了。
今天要把代码注释版本发上来,方便以后看。

补充几个小知识
erase()函数

ordinaryPlayers.erase(ordinaryPlayers.begin());

这个表示删除普通玩家队列。(头都没有了,就找不到了,因此是删完了)
更多可参考:https://blog.csdn.net/weixin_41969587/article/details/82587372
这位的博客

函数 front()

players nextPlayers;
nextPlayers=ordinaryPlayers.front();

players是一个结构体 生成了一个名叫nextPlayers的players类型的结构体。nextPlayers就是普通玩家队列最开始的那个。
更多可参考这位的博客:https://blog.csdn.net/qq_40788950/article/details/82899146

先来看题目,做好审题要求。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目的大意就是 人分vip,台球桌也分VIP。

在这里插入图片描述
在这里插入图片描述

我原来的想法:
要分以下几种情况讨论:
假设这些空出的桌子都是 空余桌子里编号最小的。//或许用switch case呢,各种情况枚举出来,定个数。这多好
1.空出来的桌子不是vip的。
进去的人:先来后到
2.空出的桌子是vip的。
看排队的人是否是vip。然后 再依次讨论
3.没有空出来的桌子,就要找到这些桌子的使用完成时间距离排队的人最近的那个桌子,找到再做处理。

我觉得分类很完善,可惜并不。。。。还不知道哪里有问题,果然是我太菜了。。。
现在总结网友的主要特点。
1.要分为三个队伍 毕竟现在都有VIP等待室了。。。。

 1. VIP队伍
 2. 普通队伍
 3. 输出队伍

2.用链表——多聪明,想要夸赞!!
用一个处理一个。多聪明。。哪像我傻bb。。。

3.排序
有两个排序的方式,

  1. 按照到达的时间排序
  2. 按照服务的时间排序

首先,处理时先按照 到达时间进行排序,处理完之后在按照服务时间排序,这样就能够输出。

输入的时间是分开的四个数字,首要做的事情就是把这些数字转换为一个整数。(按照秒来记)
第二步:进行截断。当服务时间超过2h的截断为2h
第三步:输入完信息后(如果发现是VIP客户就要要入VIP客户队列,反之亦然。并且每个桌子开始的时间都是8:00)按照到达时间进行排序
处理步骤!!!!
第一步:循环条件是两个队列只要不空,就继续循环。(这多好啊。。。太机智了)
根据题目要求,一一实现即可,。
不在开门时间的,不输出。
重要的是要准确地找出所有桌子的(当前时间的)最小时间。作为真正的当前时间。
我觉得这个大佬的代码,不能保证这个客人选择的是数字最小的桌子。
因此我思索了一下午,自己写了一个。。。但答案错误,都气哭了。 给大家看看我的代码。

#include<string>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cstdio>
using namespace std;
struct player{
	int hour, minute, second;//到达时间
	int play_time;
	int wait_time;
	int start_time;
	int time;
	int vip;//是不是vip
};
struct tables{
	int times;//服务次数
	int begin_time;
	int vip;
	int flag;//是否空闲
};
bool cmpplayer(player a, player b)
{
	return a.time < b.time;
}
bool cmpstart(player a, player b)
{
	return a.start_time < b.start_time;
}

int main()
{
	int all_player;
	int number_tables, number_vip;//总的桌子数量和vip的桌子数量
//	int number_vip[101];//vip的位置
	scanf_s("%d", &all_player);//今天的客人人数
	vector<player>OUT_P;//初始化这些个人
	vector<player>V_P;
	vector<player>O_P;
	for (int i = 0; i < all_player; i++)//输入每个人的信息
	{
		player client;
		scanf_s("%d:%d:%d %d %d", &client.hour, &client.minute, &client.second, &client.play_time,&client.vip);
		client.time = client.hour * 3600 + client.minute * 60 + client.second;
		client.play_time = client.play_time * 60;//化为秒
		if (client.play_time>2 * 3600)
			client.play_time = 7200;
		if (client.vip == 1)
			V_P.push_back(client);
		else
			O_P.push_back(client);
	}
	if (V_P.size()>0)
	sort(V_P.begin(), V_P.end(), cmpplayer);//按照时间先后排序
	if (O_P.size()>0)
	sort(O_P.begin(), O_P.end(), cmpplayer);//按照时间先后排序

	scanf_s("%d %d", &number_tables, &number_vip);
	vector<tables>table(number_tables);//桌子
	for (int i = 0; i < number_tables; i++)
	{
		table[i].vip = 0;
		table[i].begin_time = 8 * 3600;
		table[i].times = 0;
//		table[i].flag = 0;//空闲
	}
	for (int i = 0; i < number_vip; i++)
	{
		int j;
		scanf_s("%d", &j);
		table[j].vip = 1;//标注好那些桌子是 VIP桌子
	}
	
	while (O_P.size()>0 || V_P.size() > 0)
	{
		int minVacant = INT_MAX;
		int index;
		int usetable;
		int flag1;
		player nextplayer;
		for (int i = 1; i <= number_tables; i++)
		{
			if (table[i].begin_time < minVacant)
			{
				minVacant = table[i].begin_time;
				index = i;//最先空出来的房间
			}
		}
		if (V_P.size() == 0)
		{
			nextplayer = O_P.front();
			O_P.erase(O_P.begin());
		}
		else if (O_P.size() == 0)
		{
			nextplayer = V_P.front();
			V_P.erase(V_P.begin());
		}
		else
		{
			if (V_P.front().time < O_P.front().time)//V先P后
					{
						nextplayer = V_P.front();
						for (int j = 0; j < number_tables; j++)
						{
							if (table[j].vip == 1 && table[j].begin_time <= nextplayer.time)
							{
								usetable = j;
								break;
							}
							else
								usetable = index;
						}
						V_P.erase(V_P.begin());
					}
					else//O先P后
					{	
						for (int i = 1; i <= number_tables; i++)
						{
							if (O_P.front().time > table[i].begin_time)//普通用户来了,就有桌子空闲
							{
								nextplayer = O_P.front();
								O_P.erase(O_P.begin());
								usetable = i;
								flag1 = 0;
								break;
							}
							else
								flag1 = 1;
						}
						if (flag1==1)//
							{//来了没空闲桌子 index桌子是最先空闲的
								if (table[index].vip == 1)//这是一张VIP桌子
								{
									if (V_P.front().time <= table[index].begin_time)
									{
										nextplayer = V_P.front();
										V_P.erase(V_P.begin());
										usetable = index;
									}
									if (table[index].begin_time < V_P.front().time)
									{
										nextplayer = O_P.front();
										O_P.erase(O_P.begin());
										usetable = index;

									}
								}
								else
								{
									nextplayer = O_P.front();
									O_P.erase(O_P.begin());
									usetable = index;
								}
							}
						}
		}
		table[usetable].times++;
		if (table[usetable].begin_time <= nextplayer.time)
		{
			nextplayer.start_time = nextplayer.time;
			nextplayer.wait_time = 0;
		}
		else
		{
			nextplayer.start_time = table[usetable].begin_time;
			nextplayer.wait_time = table[usetable].begin_time - nextplayer.time;
		}
		table[usetable].begin_time=nextplayer.start_time+nextplayer.play_time;
		OUT_P.push_back(nextplayer);
		}
	sort(OUT_P.begin(),OUT_P.end(), cmpstart);
	for (int i = 0; i < OUT_P.size(); i++)
	{
		int waitMinutes = OUT_P[i].wait_time / 60 + (OUT_P[i].wait_time % 60<30 ? 0 : 1);
		printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", OUT_P[i].time / 3600,
			(OUT_P[i].time % 3600) / 60, OUT_P[i].time % 60,
			OUT_P[i].start_time / 3600, (OUT_P[i].start_time % 3600) / 60,
			OUT_P[i].start_time % 60, waitMinutes);
	}
	int first = 1;
	for (int i = 1; i <= number_tables; i++)
	{
		if (first)first = 0;
		else cout << " ";
		cout << table[i].times;
	}
	system("pause");
	return 0;
}

哎 这道题还是放上大佬的代码吧,真的好气哦。。。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <limits.h>
using namespace std;
 
struct players
{
    int arriveTime;
    int startServe;
    int serveTime;
    int waitTime;
    int isVIP;
};
//等待队列中的VIP客户
vector<players >vipPlayers;
//普通客户
vector<players >ordinaryPlayers;
//处理完输出信息的客户
vector<players >total;
struct tables
{
    int VIP;
    int cnt;
    int vacantTime;
};
tables t[101];
 
bool cmpPlayers(players a,players b)
{
    return a.arriveTime<b.arriveTime;
}
 
bool cmpStartServe(players a,players b)
{
    return a.startServe<b.startServe;
}
 
int main()
{
    int N,K,M,i=0;
    cin>>N;
    int hh,mm,ss,wait,vip;
    players temp;
    while(i<N)
    {
        scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&wait,&vip);
        temp.arriveTime=hh*3600+mm*60+ss;
        temp.serveTime=wait*60;
        temp.isVIP=vip;
        i++;
        if(temp.arriveTime>=3600*21)continue;
        if(vip==1)vipPlayers.push_back(temp);
        else ordinaryPlayers.push_back(temp);
    }
    cin>>K>>M;
    for(int j=1;j<=K;j++)
    {
        t[j].VIP=0;
        t[j].vacantTime=8*3600;
        t[j].cnt=0;
    }
    int tag;
    for(int j=0;j<M;j++)
    {
        cin>>tag;
        t[tag].VIP=1;
    }
 
    if(ordinaryPlayers.size()>0)sort(ordinaryPlayers.begin(),ordinaryPlayers.end(),cmpPlayers);
    if(vipPlayers.size()>0)sort(vipPlayers.begin(),vipPlayers.end(),cmpPlayers);
 
    while(ordinaryPlayers.size()>0||vipPlayers.size()>0)
    {
        int minVacant=INT_MAX;
        int minVipVacant=INT_MAX;
        int index;
        int vipIndex;
        for(int j=1;j<=K;j++)
        {
            if(t[j].vacantTime<minVacant)
            {
                minVacant=t[j].vacantTime;
                index=j;
            }
            if(t[j].VIP==1&&t[j].vacantTime<minVipVacant)
            {
                minVipVacant=t[j].vacantTime;
                vipIndex=j;
            }
        }
        if(t[index].vacantTime>=21*3600)break;
        players nextPlayers;
        if(vipPlayers.size()==0)
        {
            nextPlayers=ordinaryPlayers.front();
            ordinaryPlayers.erase(ordinaryPlayers.begin());
        }
        else if(ordinaryPlayers.size()==0)
        {
            nextPlayers=vipPlayers.front();
            vipPlayers.erase(vipPlayers.begin());
        }
        else
        {
            if(t[index].VIP==1)
            {
                if(vipPlayers.front().arriveTime<ordinaryPlayers.front().arriveTime||t[index].vacantTime>=vipPlayers.front().arriveTime)
                {
                    nextPlayers=vipPlayers.front();
                    vipPlayers.erase(vipPlayers.begin());
                }
                else
                {
                    nextPlayers=ordinaryPlayers.front();
                    ordinaryPlayers.erase(ordinaryPlayers.begin());
                }
            }
            else
            {
                if(vipPlayers.front().arriveTime<ordinaryPlayers.front().arriveTime)
                {
                    nextPlayers=vipPlayers.front();
                    vipPlayers.erase(vipPlayers.begin());
                }
                else
                {
                    nextPlayers=ordinaryPlayers.front();
                    ordinaryPlayers.erase(ordinaryPlayers.begin());
                }
            }
        }
        //控制每个人的时间在两小时之内,超过两小时按两个小时截断
        if(nextPlayers.serveTime>7200)nextPlayers.serveTime=7200;
        //这里需要记清楚:一旦有VIP桌子空闲,等待队列中的VIP客户就会选择VIP桌子,不管是否有普通桌子空闲
        if(nextPlayers.isVIP==1&&nextPlayers.arriveTime>=t[vipIndex].vacantTime)
        {
            nextPlayers.waitTime=0;
            nextPlayers.startServe=nextPlayers.arriveTime;
            t[vipIndex].vacantTime=nextPlayers.arriveTime+nextPlayers.serveTime;
            t[vipIndex].cnt++;
        }
        else
        {
            if(nextPlayers.arriveTime<=t[index].vacantTime)
            {
                nextPlayers.waitTime=t[index].vacantTime-nextPlayers.arriveTime;
                nextPlayers.startServe=t[index].vacantTime;
                t[index].vacantTime+=nextPlayers.serveTime;
            }
            else
            {
                nextPlayers.waitTime=0;
                nextPlayers.startServe=nextPlayers.arriveTime;
                t[index].vacantTime=nextPlayers.arriveTime+nextPlayers.serveTime;
            }
            t[index].cnt++;
        }
        total.push_back(nextPlayers);
    }
    sort(total.begin(),total.end(),cmpStartServe);
    for(int i=0;i<total.size();i++)
    {
        int waitMinutes=total[i].waitTime/60+(total[i].waitTime%60<30?0:1);
        printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",total[i].arriveTime/3600,
               (total[i].arriveTime%3600)/60,total[i].arriveTime%60,
               total[i].startServe/3600,(total[i].startServe%3600)/60,
               total[i].startServe%60,waitMinutes);
    }
    int first=1;
    for(int i=1;i<=K;i++)
    {
        if(first)first=0;
        else cout<<" ";
        cout<<t[i].cnt;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值