Codeforces Round #481 (Div. 3) G. Petya's Exams

http://codeforces.com/contest/978/problem/G

 

感冒是真的受不了。。。敲代码都没力气。。。

 

题目大意:

期末复习周,一共持续n天,有m场考试

每场考试有如下信息:

①si表示知道第i门课的考试时间是在第si天的时候

②di表示第i门课的考试时间

③ci表示准备第i门课需要ci天的复习

在考试的那一天不能复习。

问n天中每一天都需要干啥?

三种情况,休息(输出0),复习(输出复习那一门科目的id),考试(输出m+1)

 

思路:按照di排序(即按照截止时间),然后反过来暴力扫一遍,对于s(i)大的我们进行优先复习,所以优先队列维护一下si即可

 

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 1e3 + 5;
vector<int> day[maxn];
int n, m;
int d[maxn], s[maxn], c[maxn];
int ans[maxn];

bool solve(){
    memset(ans, -1, sizeof(ans));
    for (int i = 1; i <= m; i++){
        day[d[i]].pb(i);
        ans[d[i]] = m +  1;
    }
    priority_queue<pair<int, pair<int, int> > > que;
    for (int i = n; i >= 1; i--){
        if (day[i].size() > 0){
            for (int j = 0; j < day[i].size(); j++){
                int p = day[i][j];
                que.push(mk(s[p], mk(c[p], p)));
            }
        }
        if (ans[i] != -1) continue;
        if (que.empty()){///休息
            ans[i] = 0;
            continue;
        }
        int spos = que.top().fi;
        int restday = que.top().se.fi;
        int pos = que.top().se.se;
        que.pop();
        if (spos > i && restday > 0) return false;
        restday--;
        ans[i] = pos;
        if (restday == 0){
            continue;
        }
        que.push(mk(spos, mk(restday, pos)));
    }
    if (!que.empty()) return false;
    for (int i = 1; i <= n; i++){
        printf("%d ", ans[i]);
    }
    cout << endl;
    return true;
}

int main(){
    cin >> n >> m;
    for (int i = 1; i <= m; i++){
        scanf("%d%d%d", s + i, d + i, c + i);
    }
    if (solve() == false) puts("-1");
    return 0;
}
View Code

 

posted @ 2018-05-13 21:54  知る奇迹に  阅读(300)  评论(0编辑  收藏  举报