• NOIP2008P 排座椅


    〖NOIP2008P〗排座椅

    描述

    上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来 之后,只有有限的D对同学上课时会交头接耳。同学们在教室中坐成了M行N列,坐在第i行第j列的同学的位置是(i,j),为了方便同学们进出,在教室中设 置了K条横向的通道,L条纵向的通道。于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通 道的位置,因为如果一条通道隔开了两个会交头接耳的同学,那么他们就不会交头接耳了。

    请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生的对数最少。

    明显贪心,因为我们要在有限的改变次数内做出最好的选择。

    怎么样才能算是最好选择?

    如果我们要在行之间隔出一条通道,那么我们就应该选择两行之间交头接耳人数最多的,在这里开一条通道;

    如果我们要在列之间隔出一条通道,那么我们就应该选择两列之间交头接耳人数最多的,在这里开一条通道;

    于是我们需要对每两行和每两列之间交头接耳的人做出排序,并且记录下他们的位置,然后进行选择。

    void readp(){
         cin>>n>>m>>nk>>mk>>d;
         for(int i=1;i<n;i++) h[i].id=i;
         for(int i=1;i<m;i++) l[i].id=i;
         int x1,y1,x2,y2;
         while(d--){
               cin>>x1>>y1>>x2>>y2;
               if(x1==x2) {
                  if(y1<y2) l[y1].s++;
                  else l[y2].s++;
                  }
                  else {
                       if(x1<x2) h[x1].s++;
                       else h[x2].s++;
                      }
               }
         }

    读入并且记录下每行每列交头接耳的人数,记录下行号和列号

    void work(){
         sort(h+1,h+n,cmp);
         sort(l+1,l+m,cmp);
         sort(h+1,h+nk+1,cmp1);
         sort(l+1,l+mk+1,cmp1);
         for(int i=1;i<=nk;i++) cout<<h[i].id<<" ";
         cout<<endl;
         for(int i=1;i<=mk;i++) cout<<l[i].id<<" ";
         cout<<endl;
    }

     把人数排序,并且由于输出也需要排序,所以我们还要使用函数对结构体进行排序。

    bool cmp(node p,node q){
         return p.s>q.s;
    }
    
    bool cmp1(node p,node q){
         return p.id<q.id;
    }
  • 相关阅读:
    2013 Multi-University Training Contest 6 部分解题报告
    2013 Multi-University Training Contest 5 部分解题报告
    Codeforces Round #195 (Div. 2) 解题报告
    (转) tarjan算法
    重装SQLServer2008
    关于此博客园及其美化
    矩阵乘法
    CSP-S2019部分题解
    二维偏序
    [BOI2003]团伙
  • 原文地址:https://www.cnblogs.com/copen/p/5965598.html
Copyright © 2020-2023  润新知