会议室分配算法(最大离散)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了会议室分配算法(最大离散)相关的知识,希望对你有一定的参考价值。

参考技术A 项目需要开发一个线上会议室的预约功能,对接Zoom提供500个线上会议室,以满足用户线上会议需求。同时要求系统分配的会议室越离散越好,防止用户会议室使用超出预定时间时,影响下一场会议的进行。其中预约的会议的开始时间和结束时间只能在同一天,无法跨天。

meeting_online_roon:(存储会议室信息)

meeting_online_room_booking_detail:(存储会议室预定信息)

会议时间冲突场景:

因此sql就是:

其中:

是计算某个会议室与当前会议时间最大时间间隔。

例如会议室A预定了2场会议室: 8:00-9:00 14:00-15:00,现在要预定的会议时间为:10:00 - 12:00 。 最大时间间隔为:1小时,而不是2小时

所以总体的sql就是:(以下采用Mybatis写的)

这种方法是通过sql直接分配好会议室,不需要在内容中再进行处理,速度较快,比较简单。

HihoCoder 1590 : 紧张的会议室(区间最大+离散化)

时间限制:20000ms
单点时限:2000ms
内存限制:256MB

描述

小Hi的公司最近员工增长迅速,同时大大小小的会议也越来越多;导致公司内的M间会议室非常紧张。

现在小Hi知道公司目前有N个会议,其中第i个会议的时间区间是(Si, Ei)。 注意这里时间区间可以视为是开区间,也就是说(3, 5)和(5, 6)不会被视为是同时进行的会议。  

小Hi想知道如果他新增一个会议,时间区间是(X, Y),会不会导致出现会议室不够用的情况?

已知目前的N个会议不会导致会议室不够用。  

输入

第一行包含两个整数:N和M。  

以下N行每行两个整数Si和Ei,代表一个会议的时间区间。  

之后一行包含一个整数Q,代表小Hi询问的次数。  

以下Q行每行包含两个整数Xi和Yi,表示小Hi希望新增的会议时间。  

对于30%的数据,1 <= N, M, Q <= 1000  

对于100%的数据,1 <= N, M, Q <= 100000 0 <= Si < Ei <= 100000000 0 <= Xi < Yi <= 100000000

输出

对于每一次询问,输出YES或者NO。YES代表会议室够用,NO代表会议室不够用。

样例输入
3 1  
1 2  
3 4  
5 6  
2  
2 3  
2 4
样例输出
YES  
NO

思路: 前缀和性质,[x,y]覆盖,则sum[x]++,sum[y+1]--,正好题目给定的是左开右闭[x,y),则直接离散化,求区间最大。

开始用树状数组,一直超时。后来改成倍增就ok了。

 

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1000010;
int x[maxn],y[maxn],s[maxn],e[maxn],sum[maxn],q[maxn];
int tmp,tmp2,cnt,R[maxn],dp[maxn][20];
int max(int a,int b){ if(a>b) return a; return b;}
int read()
{
    int res=0; char c=getchar();
    while(c>9||c<0) c=getchar();
    while(c>=0&&c<=9){res=res*10+c-0; c=getchar(); } 
    return res;
}
int RMQ()
{
    for(int i=1;i<=cnt;i++) dp[i][0]=sum[i];
    for(int i=1;i<20;i++)
     for(int j=1;j+(1<<i)<cnt;j++)
      dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
int query(int l,int r)
{
    int k=log2(r-l+1);
    return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
    int N,M,Q,i,j,Max=0;
    scanf("%d%d",&N,&M);
    for(i=1;i<=N;i++){
        scanf("%d%d",&s[i],&e[i]);
        s[i]++; e[i]++;
        q[++cnt]=s[i]; 
        q[++cnt]=e[i];
    }
    scanf("%d",&Q);
    for(i=1;i<=Q;i++){
        scanf("%d%d",&x[i],&y[i]);
        x[i]++;  y[i]++;
        q[++cnt]=x[i];
        q[++cnt]=y[i];
    }
    sort(q+1,q+cnt+1);
    unique(q+1,q+cnt+1);
    for(i=1;i<=N;i++){
        tmp=lower_bound(q+1,q+cnt+1,s[i])-q; sum[tmp]++; 
        tmp=lower_bound(q+1,q+cnt+1,e[i])-q; sum[tmp]--;
    }
    for(i=1;i<=cnt;i++) {
         sum[i]+=sum[i-1];
         Max=max(Max,sum[i]);
    }
    RMQ();
    for(i=1;i<=Q;i++){
        tmp=lower_bound(q+1,q+cnt+1,x[i])-q;
        tmp2=lower_bound(q+1,q+cnt+1,y[i])-q;
        if(query(tmp,tmp2-1)<M) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

 

 

超时代码:

技术分享图片
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=5000010;
int x[maxn],y[maxn],s[maxn],e[maxn],sum[maxn],q[maxn];
int tmp,tmp2,cnt,R[maxn];
int max(int a,int b){ if(a>b) return a; return b;}
int read()
{
    int res=0; char c=getchar();
    while(c>9||c<0) c=getchar();
    while(c>=0&&c<=9){res=res*10+c-0; c=getchar(); } 
    return res;
}
void add(int i,int val)
{
    while(i<=cnt){
        R[i]=max(R[i],val);
        i+=(-i)&i;
    }
}
int query(int l,int r)
{
    int res=0;
    while(l<=r&&r){
        while(r-(-r)&r>=l&&r) {
            res=max(res,R[r]);
            r-=(-r)&r;
        }
        if(r>=l) res=max(res,sum[r--]);
    } return res;
}
int main()
{
    int N,M,Q,i,j,Max=0;
    scanf("%d%d",&N,&M);
    for(i=1;i<=N;i++){
        scanf("%d%d",&s[i],&e[i]);
        s[i]++; e[i]++;
        q[++cnt]=s[i]; 
        q[++cnt]=e[i];
    }
    scanf("%d",&Q);
    for(i=1;i<=Q;i++){
        scanf("%d%d",&x[i],&y[i]);
        x[i]++;  y[i]++;
        q[++cnt]=x[i];
        q[++cnt]=y[i];
    }
    sort(q+1,q+cnt+1);
    unique(q+1,q+cnt+1);
    for(i=1;i<=N;i++){
        tmp=lower_bound(q+1,q+cnt+1,s[i])-q; sum[tmp]++; 
        tmp=lower_bound(q+1,q+cnt+1,e[i])-q; sum[tmp]--;
    }
    for(i=1;i<=cnt;i++) {
         sum[i]+=sum[i-1];
         add(i,sum[i]);
         Max=max(Max,sum[i]);
    }
    for(i=1;i<=Q;i++){
        if(Max>M) printf("NO\n");
        else {
            tmp=lower_bound(q+1,q+cnt+1,x[i])-q;
            tmp2=lower_bound(q+1,q+cnt+1,y[i])-q;
            if(query(tmp,tmp2-1)<M) printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}
View Code

 

以上是关于会议室分配算法(最大离散)的主要内容,如果未能解决你的问题,请参考以下文章

关于离散数学的编程问题(数理逻辑部分)

Final-阶段站立会议2

Final-阶段站立会议3

javascript 分配Adobe Connect会议室参与者

ruby 在不同的插槽中重新分配会议

华为机试真题 C++ 实现最大社交距离