luogu1056:排座椅:模拟=统计+排序:NOIP2008普及T2

97 篇文章 1 订阅
93 篇文章 0 订阅

题目链接:该题是luogu试炼场的2-1:T4


试炼场2-1题解包:

2-1简单模拟 
题号题目备注
1003铺地毯逆向查找
1067多项式输出分段模拟
1540机器翻译循环队列
1056排座椅统计排序
1328生活大爆炸版石头剪刀布暴力模拟
1563玩具谜题环形思维

题目大意:

1 在n*m的矩阵里,有k对位置,需要用x条横线和y条竖线,将这k对位置尽可能地切分开:

2 借用原题的图,非常清晰:3对位置,用两竖一横强行切割:


解题思路:

1 数据很小,而且是求最优解,所以还是从模拟过程去想;

2 要切尽可能多的对,那就排序咯;

3 然后就结束了。。。。


上代码:

//luogu试炼场2-1:4:1056:排座位 

//解法分析:
//1 统计每行每列需要切割的情况(有人相邻,就可能要切割)
//2 排序,找出最需要切割的行/列
//3 标记前面k行,l列
//4 按原始序号输出 

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mx=2005;

int n,m,k,l,d;
struct nod{int s,o;}ha[mx],le[mx];
int xx[mx],yy[mx];

bool cmp(nod x,nod y) { return x.s>y.s; }
int main()
{
    memset(xx,0,sizeof(xx));
    memset(yy,0,sizeof(yy));
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) { ha[i].o=i;ha[i].s=0; }
    for(int i=1;i<=m;i++) { le[i].o=i;le[i].s=0; }
    
    scanf("%d %d",&k,&l);
    scanf("%d",&d);
    
    int x,y,a,b;
    for(int i=1;i<=d;i++)
    {
        scanf("%d %d",&x,&y);
        scanf("%d %d",&a,&b);
        if(x==a)//同行 
        {
            if(y>b) le[b].s++;
            else if(b>y) le[y].s++;
        }
        else if(y==b)//同列 
        {
            if(x>a) ha[a].s++;
            else if(a>x) ha[x].s++;
        }
    }
    sort(ha+1,ha+1+n,cmp);
    sort(le+1,le+1+m,cmp);
    for(int i=1;i<=k;i++) xx[ha[i].o]=1;
    for(int i=1;i<=l;i++) yy[le[i].o]=1;
    
    for(int i=1;i<=n;i++) if(xx[i]) printf("%d ",i);printf("\n");
    for(int i=1;i<=m;i++) if(yy[i]) printf("%d ",i);printf("\n");
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值