Description
Petya在大学学习。n个考试日作为本学期的结束。Petya需要在这些特殊的日子里通过m个考试。此问题中的特殊日期从1到n编号。
每个考试有三个值:
- si - 第i场考试被宣布的日期
- di - 第i次考试进行考试的日期(si<disi<di),
- ci - Petya需要为第i次考试做准备的天数。
Petya应该在si和di-1之间的天内准备第i次考试,包括在内。
Petya每天有三种活动类型:花一天假装咸鱼(休息),花一天时间通过一次考试,或花一天准备一次考试。所以他不能一天通过/准备多次考试。他不能在一天内混合他的活动。如果他在第j天准备第i次考试,那么si≤j<di。
允许在准备考试时休息一段时间,并在连续几天内为不同考试做准备。所以准备考试不需要连续几天完成。
找到Petya为所有考试做准备并通过考试的时间表,或者报告说这是不可能的。
Input
第一行包含两个整数n和m(2≤n≤100,1≤m≤n) - 天数和考试次数。
以下m行中的每一行都包含三个整数si,di,ci(1≤si<di≤n,1≤ci≤n)
保证所有的考试将在不同的日子。
Output
如果Petya无法准备并通过所有考试,请输出-1。 在肯定答案的情况下,打印n个整数代表n天,其中第j个数字是:
- (m + 1),如果第j天是一些考试的某一天
- 0,如果在第j天彼佳会休息
- i(1≤i≤m),如果彼佳将在第j天准备第i次考试(彼佳为每次考试准备的总天数应该严格等于准备所需的天数)
考试从1开始编号。
如果有多个时间表,请打印其中的任何一个。
Sample Input
Input
5 2
1 3 1
1 5 1
Output
1 2 3 0 3
Input
3 2
1 3 1
1 2 1
Output
-1
Input
10 3
4 7 2
1 10 3
8 9 1
Output
2 2 2 1 1 0 4 3 4 4
Hint
例如,第一个例子中,Petya可以在第一天为第一天的考试做准备,在第二天为第二天的考试做好准备,在第三天通过考试1,在第四天咸鱼,在第五天通过考试2。 所以,他可以准备并通过所有考试。
在第二个例子中,有三天和两次考试。 所以,Petya只有一天做准备(因为在其他两天里他应该考试)。 然后Petya无法准备并通过所有考试。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
struct Node
{
int s, d, c, pos;
} cls[111];
int ans[111];
bool cmp(Node a, Node b)
{
return a.d < b.d;
}
int main()
{
int n, m;
bool flag = 1;
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++)
{
scanf("%d %d %d", &cls[i].s, &cls[i].d, &cls[i].c);
cls[i].pos = i + 1;//为第几场考试做准备需要存入ans数组的数
ans[cls[i].d] = m + 1;//把考试那天m+1先存入ans数组
}
sort(cls, cls + m, cmp);//根据考试日期从小到大排序
//类似会场安排,贪心
for (int i = 0; i < m && flag; i++)//有m场考试,进行m次循环
{
int k = cls[i].s;//先把第i场考试的宣布日期赋给k
//每准备了一天就把k往后推一天,如果到考试日期了
//还没准备完,flag赋予0,结束循环
while (cls[i].c)//循环一次,需要准备的天数就减一
{
if (k >= cls[i].d)//此时在循环中,说明需要准备的天数还没减到0
//k就已经到了考试日期,即不能通过考试
{
flag = 0;
break;
}
if (!ans[k])//ans数组等于0时,进入if,即这一天不是考试日期
//因为前面已经把ans数组里考试日期赋成了m+1
{
ans[k] = cls[i].pos;//把ans数组第k天赋成pos
cls[i].c--;//需要准备的天数就少了一天
}
k++;//日期往后加一天
}
}
if (flag)//flag为1,说明考试都准备完了
{
for (int i = 1; i <= n; i++)
{
if (i-1)
printf(" ");
printf("%d", ans[i]);
}
}
else
{
printf("-1");
}
return 0;
}