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;
}