实训三#3.9占位置

[problem description] the classroom seats in sun's school can be reserved every day.
A person can occupy multiple seats and must have consecutive seats. If he can't occupy so many seats he requires, he won't want any more. In order to reduce the difficulty, seats are allocated from small to large according to the seat number each time, and seats are allocated by the first adaptation method.
[input form] multiple groups of data are input.
Each group of data input seat rows n, 0 < n < = 100 (the number of seats is equal, the seats are sorted from left to right in each row, and the rightmost seat in the first row and the first seat in the second row are regarded as continuous seats), m (0 < m < = min (100, n * n)) individuals.
Then enter K (0 < K < = 100), and finally enter K commands.
There are only two commands:
1. In ID num (for ID, 0 < = ID < m, Num seats shall be occupied. If no consecutive num (0 < num < = 20) seats are occupied, the command is invalid)
2. Out ID (represents that ID wants to release all the seats he previously occupied)
Note: if the ID has occupied a seat before and has not been released, then its in command is invalid,
If Id has not occupied a seat before, his out command is also invalid.
[output form] output yes or no for each in command. If the command is valid, output yes. If it is invalid, output No.
After Yes No, there is only carriage return without any other characters.
[sample input]

4 10

9

in 1 7

in 2 3

in 3 3

in 3 3

in 4 3

out 2

in 5 6

out 3

in 5 6

【样例输出】

yes
yes

yes

no

yes

yes

no

yes

yes

【样例说明】
【评分标准】

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct seat//声明一个结构体
{
    int id;//借用人的学号
    int len;//借用的座位个数
    bool Is_use;//标记这些连续的座位是否仍在使用
    seat(int i,int l,bool u)//构造函数,便于插入vector中
    {
        id=i;
        len=l;
        Is_use=u;
    }
};

int main()
{
    vector<seat> v;//容器
    vector<seat>::iterator it;//迭代器
    int n,m,k;//n - 行数 m - 人数(好像没用) k - 访问数
    int seatleft;//座位剩余数
    cin>>n>>m>>k;
    string op;//操作字符串
    seatleft=n*n;//初始化剩余座位
    while(k--)
    {
        cin>>op;//输入操作
        if(op=="in")//如果是借用座位的话
        {
            int id,num;
            cin>>id>>num;//输入学号,借用座位数
            bool Is_exist=false;//该学号是否已经借过座位
            for(it=v.begin();it!=v.end();it++)
            {
                if(it->id==id)
                {
                    Is_exist=true;
                    break;
                }
            }
            if(seatleft<num||Is_exist) cout<<"no"<<endl;//两种情况输出no
            //一是剩余座位小于需求座位,二是这个学号已经借过座位了
            else//可能可以借到座位,下面开始尝试分配
            {
                bool flag=false;//标记是否将别人释放的座位借出
                for(it=v.begin();it!=v.end();it++)//遍历所有记录
                {
                    if(it->Is_use==false&&it->len>=num)//如果借用情况是未借用
                    //且上次借用的长度大于等于本次借用长度
                    {
                        cout<<"yes"<<endl;//能够借到座位,直接输出yes
                        int temp=it->len;//储存上次借用座位的长度
                        it->Is_use=true;//是否使用更新为已使用
                        it->len=num;//更改长度为该次借用长度
                        v.insert(it+1,seat(id,temp-num,false));//将未借用的部分接到这次借用的后面
                        seatleft-=num;//更新剩余位置数
                        flag=true;//借用成功
                        break;//退出循环
                    }
                }
                if(!flag)//如果上面方法借用不成功,开始尝试第二种方式分配
                {
                    int sum=0;//求出所有已借用和不符合要求的座位数
                    for(it=v.begin();it!=v.end();it++)
                        sum+=it->len;
                    if(sum+num>n*n) cout<<"no"<<endl;//如果整个座位的最后面没有符合条件数量的座位,输出no
                    else//说明这位同学可以借到最后面的座位
                    {
                        cout<<"yes"<<endl;
                        seatleft-=num;
                        v.push_back(seat(id,num,true));
                    }
                }
            }
        }
        else//归还座位
        {
            int id;
            cin>>id;//归还同学的id
            bool flag=false;
            bool Is_exist=false;//是否存在该名同学
            for(it=v.begin();it!=v.end();it++)
            {
                if(it->id==id)
                {
                    Is_exist=true;
                    break;
                }
            }
            if(!Is_exist)//如果不存在
            {
                cout<<"no"<<endl;//输出no
            }
            else
            {
                for(it=v.begin();it!=v.end();it++)
                {
                    if(it->id==id&&it->Is_use==true)
                    {
                        cout<<"yes"<<endl;
                        it->Is_use=false;
                        flag=true;//这个同学借了座位,且没有归还
                        seatleft+=it->len;
                        break;
                    }
                }
                if(!flag) cout<<"no"<<endl;//借了座位已经归还
                for(it=v.begin();it!=v.end();it++)//将连续的几块座位结合成一整块空位置
                {
                    if(it->Is_use==false&&(it+1)->Is_use==false)
                    {
                        it->len+=(it+1)->len;
                        v.erase(it+1);
                        it--;//由于在erase的时候迭代器会向后移一位
                        //所以我们要自行it--,从而复原其状态
                    }
                }
            }
        }
    }
    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值