CCF-CSP 201609-2火车购票 详细思路及解题过程 满分题解

CCF-CSP 201609-2火车购票 详细思路及解题过程 满分题解

题目链接:CCF-CSP201609-2火车购票

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

90分思路(结尾附满分思路,该思路只用于记录):

  • 设置一个数组a[N]用于记录第i排坐了多少个人,设置一个数组b[N][6]标记第i排是否被坐,坐了标记为1(用于输出)
  • 设置一个find函数,用于找到最小的排数
  • 在主函数中,遍历找到的那一排,判断是否被坐,如果没有被坐则可以坐,直接输出对应的座位号
  • 此思路只有90分是因为忽略了条件安排在编号最小的几个空座位中(不考虑是否相邻)所有购票数量之和不超过100

具体代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e4+10;
int n;
int a[N];//存储第i排坐了多少个
int b[N][6];//标记第i排是否被坐,坐了标记为1(用于输出)
//找到最小的排数
int find(int x)
{
    int flag = 1;
    for(int i=1;i<=N;i++)
    {
        if(x<=5-a[i])//判断第i排是否可以坐下
        {
            flag = i;
            break;
        }
    }
    return flag;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        int t = find(x);
        a[t]+=x;//第t排被坐的数量+x
        for(int j=1,k=1;j<=5&&k<=x;j++)
        {
            if(b[t][j]==1)//如果第j个位置被坐
            {
                continue;
            }
            else
            {
                b[t][j]=1;//第j个位置被坐
                k++;//k用来记录是否坐满了x个
                cout<<5*(t-1)+j<<" ";//简单的计算输出
            }
        }
        cout<<endl;
    }
    return 0;
}

100分修改思路:

  • 在90分代码的基础上,需要判断当前的排数是否超过了20
  • 对于超过20排的数据需要进行特殊处理,即应该安排在编号最小的几个空座位中(不考虑是否相邻)
  • 在进行特殊处理时,只需要双重循环遍历找到编号最小的位置就可以了

具体代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e2+10;
int n;
int a[N];//存储第i排坐了多少个
int b[N][6];//标记第i排是否被坐,坐了标记为1(用于输出)
//找到最小的排数
int find(int x)
{
    int flag = 1;
    for(int i=1;i<=N;i++)
    {
        if(x<=5-a[i])//判断第i排是否可以坐下
        {
            flag = i;
            break;
        }
    }
    if(flag>20)return N;//最多为20排
    return flag;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x;cin>>x;
        int t = find(x);
        if(t==N)//当超过20排时就选择编号最小的位置
        {
            int k =1;//k用来记录是否坐满了x个
            //两重循环中的k<=x都不能少
            for(int i=1;i<=N&&k<=x;i++)
            {
                for(int j=1;j<=5&&k<=x;j++)
                {
                    if(b[i][j]==0)
                    {
                        k++;
                        b[i][j]=1;//标记
                        a[i]++;//人数加一
                        cout<<5*(i-1)+j<<" ";
                    }
                }
            }
            cout<<endl;
        }
        else{
        a[t]+=x;//第t排被坐的数量+x
        for(int j=1,k=1;j<=5&&k<=x;j++)
        {
            if(b[t][j]==1)//如果第j个位置被坐
            {
                continue;
            }
            else
            {
                b[t][j]=1;//第j个位置被坐
                k++;//k用来记录是否坐满了x个
                cout<<5*(t-1)+j<<" ";//简单的计算输出
            }
        }
        cout<<endl;
    }
    }
    return 0;
}
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值