java蓝桥杯练习 会议中心

java蓝桥杯练习 会议中心

资源限制
时间限制:2.0s 内存限制:512.0MB
  会议中心  Siruseri政府建造了一座新的会议中心。许多公司对租借会议中心的会堂很感兴趣,他们希望能够在里面举行会议。
  对于一个客户而言,仅当在开会时能够独自占用整个会堂,他才会租借会堂。会议中心的销售主管认为:最好的策略应该是将会堂租借给尽可能多的客户。显然,有可能存在不止一种满足要求的策略。
  例如下面的例子。总共有4个公司。他们对租借会堂发出了请求,并提出了他们所需占用会堂的起止日期(如下表所示)。
在这里插入图片描述

上例中,最多将会堂租借给两家公司。租借策略分别是租给公司1和公司3,或是公司2和公司3,也可以是公司1和公司4。注意会议中心一天最多租借给一个公司,所以公司1和公司2不能同时租借会议中心,因为他们在第九天重合了。
  销售主管为了公平起见,决定按照如下的程序来确定选择何种租借策略:首先,将租借给客户数量最多的策略作为候选,将所有的公司按照他们发出请求的顺序编号。对于候选策略,将策略中的每家公司的编号按升序排列。最后,选出其中字典序最小[1]的候选策略作为最终的策略。
  例中,会堂最终将被租借给公司1和公司3:3个候选策略是{(1,3),(2,3),(1,4)}。而在字典序中(1,3)<(1,4)<(2,3)。
  你的任务是帮助销售主管确定应该将会堂租借给哪些公司。
输入格式
  输入的第一行有一个整数N,表示发出租借会堂申请的公司的个数。第2到第N+1行每行有2个整数。第i+1行的整数表示第i家公司申请租借的起始和终止日期。对于每个公司的申请,起始日期为不小于1的整数,终止日期为不大于109的整数。
输出格式
  输出的第一行应有一个整数M,表示最多可以租借给多少家公司。第二行应列出M个数,表示最终将会堂租借给哪些公司。
数据规模和约定
  对于50%的输入,N≤3000。在所有输入中,N≤200000。
样例输入
4
4 9
9 11
13 19
10 17
样例输出
2
1 3

[1] 字典序指在字典中排列的顺序,如果序列l1是序列l2的前缀,或者对于l1和l2的第一个不同位置j,l1[j]<l2[j],则l1比l2小。

//java code
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
    static int[] a,b,c,d,e,f;
    static int g[][];
    static int n=0,fin=0,max=0;
    public static void main(String[] args) throws Exception{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String s=br.readLine();
        n=Integer.parseInt(s);
        a=new int[n+1];
        b=new int[n+1];
        d=new int[n+1];
        for (int i = 1; i <= n; i++) {
            s=br.readLine();
            String sa[]=s.split(" ");
            a[i]=Integer.parseInt(sa[0]);
            b[i]=Integer.parseInt(sa[1]);
            if(max<b[i]) max=b[i];
        }
        c=new int[max+1];
        for (int i = 1; i <= n; i++) {
            if(c[b[i]]==0){
                c[b[i]]=i;
            }else {
                if(a[i]>a[c[b[i]]]){
                    for (int j = 1; j <=n; j++) {
                        if(d[j]==0){
                            d[j]=c[b[i]];
                            c[b[i]]=i;
                            break;
                        }
                    }
                }
            }
        }
        g=new int[2][n+1];
        for (int i = 1; i <= max; i++) {
            if(c[i]!=0)
                getcs(c[i]);
        }
        for (int i = 1; i <= n; i++) {
            if(fin<g[0][i]) fin=g[0][i];
        }
        for(int k=max;k>=1;k--){
            if(c[k]==0)  continue;
            int i=c[k];
            if(g[0][i]==fin) continue;
            for (int j = b[i]+1; j <= max; j++) {
                if(j==max){
                    g[0][i]=0;
                    g[1][i]=0;
                    continue;
                }
                if(c[j]==0) continue;
                if(g[0][c[j]]==0) continue;
                if((g[0][c[j]]==g[0][i]+1)&(a[c[j]]>b[i])) break;
                if(g[0][c[j]]>g[0][i]+1){
                    g[0][i]=0;
                    g[1][i]=0;
                    break;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            if(d[i]!=0){
                getcs1(d[i]);
            }else break;
        }
        e=new int[fin+1];
        f=new int[fin+1];
        int xh=1;
        for (int i = 1; i <=n ; i++) {
            if(g[0][i]==0)  continue;
            if(e[g[0][i]]!=0) continue;
            if(fink(i)==1){
                f[xh]=i;
                xh++;
                e[g[0][i]]=i;
                dealsq(i);
            }
        }
        System.out.println(fin);
        for (int i = 1; i <=fin; i++) {
            System.out.print(""+f[i]+" ");
        }
        System.out.println();
    }
    static void getcs(int x){
        int cs=0;
        for (int i = a[x]-1; i >0 ; i--) {
            if(c[i]!=0){
                cs=g[0][c[i]];
                if(cs!=0){
                    break;
                }
            }
        }
        for (int i = a[x]; i <b[x] ; i++) {
            if(c[i]!=0){
                if(g[0][c[i]]>cs+1) return;
            }
        }
        g[0][x]=cs+1;
        g[1][x]=1;
    }
    static void getcs1(int x){
        int cs=0;
        int bb=g[0][c[b[x]]];
        if(bb==0) return;
        for (int i = a[x]-1; i > 0; i--) {
            if(c[i]!=0){
                cs=g[0][c[i]];
                if(cs!=0)
                    break;
            }
        }
        if(cs+1<bb) return;
        g[0][x]=cs+1;
        g[1][x]=1;
    }
    static int fink(int x){
        int ls[]=new int[fin+1];
        int bb=0,cc=0,sc=0,ec=0;
        int cs=g[0][x];
        for (int i = cs-1; i >=1 ; i--) {
            if(e[i]!=0){
                bb=e[i];
                sc=i;
                break;
            }
        }
        if(bb!=0){
            ls[sc]=b[bb];
            for (int i = b[bb]+1; i < a[x]; i++) {
                if(c[i]==0) continue;
                if(g[0][c[i]]==0) continue;
                if(ls[g[0][c[i]]]!=0) continue;
                if(a[c[i]]<=ls[g[0][c[i]]-1]) continue;
                ls[g[0][c[i]]]=b[c[i]];
            }
            if(ls[cs-1]==0) return 0;
            if(ls[cs-1]>=a[x]) return 0;
        }
        for (int i = cs+1; i <=fin; i++) {
            if(e[i]!=0){
                cc=e[i];
                ec=i;
                break;
            }
        }
        if(cc!=0){
            ls[ec]=a[cc];
            for (int i = a[cc]-1; i >b[x] ; i--) {
                if(c[i]==0) continue;
                if(g[0][c[i]]==0) continue;
                if(i>=ls[g[0][c[i]]+1]) continue;
                ls[g[0][c[i]]]=Math.max(a[c[i]],ls[g[0][c[i]]]);
            }
            if(ls[cs+1]==0) return 0;
            if (ls[cs+1]<=b[x]) return 0;
        }
        return 1;
    }
    static void dealsq(int x){
        int cs=g[0][x];
        for (int i = b[x]-1; i >=1 ; i--) {
            if(c[i]==0) continue;
            if(g[0][c[i]]==0) continue;
            int dcs=g[0][c[i]];
            if(dcs==cs){
                g[0][c[i]]=0;
                g[1][c[i]]=0;
                continue;
            }
            if(dcs==cs-1){
                if(i>=a[x]){
                    g[0][c[i]]=0;
                    g[1][c[i]]=0;
                    continue;
                }
            }
            if(dcs==cs-2) break;
        }
        for (int i = b[x]+1; i <=max ; i++) {
            if(c[i]==0) continue;
            if(g[0][c[i]]==0) continue;
            int dcs=g[0][c[i]];
            if(dcs==cs){
                g[0][c[i]]=0;
                g[1][c[i]]=0;
                continue;
            }
            if(dcs==cs+1){
                if(b[x]>=a[c[i]]){
                    g[0][c[i]]=0;
                    g[1][c[i]]=0;
                    continue;
                }
            }
            if(dcs==cs+2) break;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值