3 条题解

  • 0
    @ 2024-11-17 15:26:51

    锐评

    不得不说作为一道模拟题它是非常好的,类似于廊桥分配。
    但是谴责黑心大样例!!!

    题意

    对于每一个文件,选择一个编号最小以及等待时间最短的打印机进行打印。

    40Pts TLE

    使用一个优先队列存储每个节点信息,然后每次取队顶,对于每一次时间增加我们重新更新队列。
    由于优先队列不支持直接修改,也没有迭代器,因此我们只能一个一个更新出队再进队,所以非常费时。

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn int(2e5)
    #define _for(a,b,c) for(int i = a;i <= b;i+=c)
    struct p{
    	int nxt,id;
    	bool operator < (const struct p &a) const{
    		return nxt == a.nxt ? id > a.id : nxt > a.nxt;
    	}
    };
    priority_queue<p> q;
    struct wj{
    	int s,t,id;
    } w[maxn];
    bool cmp(wj A,wj B){return A.t < B.t;}
    int read(){
        int X=0,w=0; char c=0;
        while(c<'0'||c>'9') {w|=c=='-';c=getchar();}
        while(c>='0'&& c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar();
        return w? -X : X;
    }
    vector<int> ans[maxn+10];
    int c1[maxn+10],c2[maxn+10];
    signed main(){
    	//freopen("print3.in","r",stdin);
    	//freopen("print.txt","w",stdout);
    	int n = read(),m = read();
    	_for(1,n,1) w[i].s = read(),w[i].t = read(),w[i].id = i;
    	sort(w+1,w+1+n,cmp);
    	_for(1,m,1) q.push(p{0,i}); 
    	_for(1,n,1){
    		int tot = 0;
    		while(!q.empty()){
    			int tmp1 = q.top().nxt;
    			tmp1 -= (w[i].t - w[i-1].t);
    			if(tmp1 < 0) tmp1 = 0;
    			int tmp2 = q.top().id;
    			q.pop();
    			c1[++tot] = tmp1,c2[tot] = tmp2;
    		}
    		for(int j = 1;j <= tot;j++){
    			q.push((p){c1[j],c2[j]});
    		}
    		//printf("%d %d\n",q.top().nxt,q.top().id);
    		ans[q.top().id].push_back(w[i].id);
    		int tmp = q.top().nxt + w[i].s;
    		int tmp2 = q.top().id;
    		q.pop();
    		q.push((p){tmp,tmp2}); 
    	}
    	_for(1,m,1){
    		printf("%d ",ans[i].size());
    		sort(ans[i].begin(),ans[i].end());
    		for(int j = 0;j < ans[i].size();j++) printf("%d ",ans[i][j]);
    		printf("\n");
    	}
    	return 0;
    } 
    

    About 60 Pts

    这个原因各有吧。。。
    至少我自己是没有考虑没有打印机空闲的情况。

    正解

    还是优先队列,但是这次变成了两个。
    一个用于存储没有打印任务的打印机,一个存储有任务的打印机。
    如果有打印机没有打印任务直接选择里面最小的。
    否则,找到等待时间最小的那一个。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 200010;
    #define int long long
    int n,m;
    struct node{int s,t,id;}a[maxn];
    bool cmp(node &A,node &B){return A.t<B.t;}
    struct print{
        int id,t;
        bool operator < (const print &x)const{
            return t==x.t ? id>x.id : t>x.t;
        }
    };    
    priority_queue <print> q;
    priority_queue <int,vector<int>,greater<int> > v;
    priority_queue <int,vector<int>,greater<int> > ans[maxn];
    int read(){
        int X=0,w=0; char c=0;
        while(c<'0'||c>'9') {w|=c=='-';c=getchar();}
        while(c>='0'&& c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar();
        return w? -X : X;
    }
    signed main(){
        int n = read(),m = read();
        for(int i = 1;i <= n;i++) a[i].s = read(),a[i].t = read(),a[i].id=i;
        sort(a+1,a+1+n,cmp);
        for(int i = 1;i <= m;i++) v.push(i);
        for(int i = 1;i <= n;i++){
            while(q.size() && q.top().t <= a[i].t) v.push(q.top().id),q.pop();
            if(v.empty()) ans[q.top().id].push(a[i].id),q.push({q.top().id,q.top().t+a[i].s}),q.pop();
            else ans[v.top()].push(a[i].id),q.push({v.top(),a[i].s+a[i].t}),v.pop();
        }
        for(int i = 1;i <= m;i++){
            printf("%d ",ans[i].size());
            for(int j = 0;j < ans[i].size();j++){
                while(!ans[i].empty()){
                    printf("%d ",ans[i].top());
                    ans[i].pop();
                }      
            }
            printf("\n");
        }
        if(1+1==3) cout << "I_I_A_K_I_O_I!!!!";
        return 0;
    }
    

    信息

    ID
    93
    时间
    3000ms
    内存
    512MiB
    难度
    4
    标签
    递交数
    1400
    已通过
    255
    上传者