1056 排座椅
这个题其实就是一个很简单的模拟,当然也可以说是贪心
最后的输出的数表示a a+1之间有通道
题意不用解释太多了
这里我们需要自己总结一个经验
如果相邻的两行有许多组说话的同学,那么在这两行中间加一条过道是非常划算的
同理,列也是如此
所以呢
只要找出划分,哪些相邻的两行和相邻的两列,可以隔开的同学最多
就是所谓的答案了
x[i]表示i行和i+1行之间能隔开的同学之间的最大组数 y表示列 同理
可见我们需要统计
因为保证他们前后相邻或者左右相邻,所以他们不是一行就是一列
然后,我们需要将两个x y数组进行排序
为什么要排序,就是说找到一个更大的分开组数,将行分开和列分开的最大组数分别进行排序
然后直接进行输出
但是这个桶排序,非常玄妙
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int m,n,k,l,d;//变量名最好起与题目一致的
int x[1005],y[1005];//横纵坐标数组
int c[1005],o[1005];//桶排要用的数组
int main()
{
scanf("%d%d%d%d%d",&m,&n,&k,&l,&d); //输入行列 还有横项纵项通道
for(int i=1;i<=d;i++)
{
int xi,yi,pi,qi;
scanf("%d%d%d%d",&xi,&yi,&pi,&qi);
if(xi==pi) //非行即列
x[min(yi,qi)]++;//表示隔开这两排的价值
else
y[min(xi,pi)]++; //过道与前一个坐标保持一致
}
for(int i=1;i<=k;i++){//进行桶排
int maxn=-1;//每次都得扫描
int p;
for(int j=1;j<m;j++){
if(y[j]>maxn){
maxn=y[j];
p=j; //求最大值
}
}
y[p]=0;//最大的清零
c[p]++;//桶排不解释
}
//竖着的
for(int i=1;i<=l;i++)
{
int maxn=-1;
int p;
for(int j=1;j<n;j++)
{
if(x[j]>maxn)
{
maxn=x[j];
p=j;
}
}
x[p]=0; //同上
o[p]++;
} //将行分开和列分开的最大组数分别进行排序
for(int i=0;i<1005;i++)//输出答案
{
if(c[i])//表示需要隔开这行
printf("%d ",i); //摆上座椅
}
printf("\n");
for(int i=0;i<1005;i++)
{
if(o[i])
printf("%d ",i); //同上
}
return 0;
}