题目图片:
用到的知识点:
1.优先队列与内嵌比较函数的结合
2.队列的stl库的调用
3.vector容器
难点解答:
1.
2. push-back()
3. 内嵌比较函数:
4.
题目大致思路:
1.把需要的每天的人数d[i]数组预处理为第i天刚开始工作的人数。
2.两个队列,一个工作队列q,一个休息队列q1。
3.本题采用了贪心的思想,每次都先选工作时间最长的那个人。
4.寻找的时候两个循环:
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define maxn 2019
int W[maxn],d[maxn];
vector<int>v[maxn];
struct node
{
int id,cnt,next;
node(int x,int y,int z)
{
id=x;
cnt=y;
next=z;
}
bool operator <(const node& r)const
{
return cnt<r.cnt;
}//优先队列是从大到小排序,q.top(),输出的是最大值
//但是这只是针对单个类型int而言
//本题需要对结构体中的cnt由大到小进行排序,并且输出最大的
//因此用到了结构体内嵌比较函数,cnt<r.cnt,表示先输出cnt大的。
};
int main()
{
int m,n,w,h;
cin>>m>>n>>w>>h;
for(int i=1; i<=m; i++)
{
cin>>W[i];
}
d[0]=0;
for(int i=1; i<=n; i++)
{
cin>>d[i];
}
priority_queue<node>q;
queue<node>q1;
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=i+w-1; j++)
{
d[j]-=d[i];
}
}//原来的d[i]数组是用来记录每一天需要用多少人的
//现在把它预处理成有几个人需要在第i天开始工作
for(int i=1; i<=m; i++)
{
q.push(node(i,W[i],1));//这里的1也可以写成0,2等,不影响
//就是进行一下初始化
}
int f=1;
for(int i=1; i<=n; i++)
{
while(q1.size()&&q1.front().next==i)
{
node now=q1.front();
q.push(now);
q1.pop();
}
while(d[i]--)
{
if(q.size()==0)
{
f=0;
break;
}
node now=q.top();
q.pop();
if(i+w-1>n)
{
f=0;
break;
}//如果它没有满足连续的工作时间
v[now.id].push_back(i);
now.next=i+w+h;
now.cnt-=w;
if(now.cnt!=0)
q1.push(now);
}
}
if(f)
{
cout<<1<<endl;
int i,j;
for(i=1; i<=m; i++)
{
int len=v[i].size();
for(j=0; j<len-1; j++)
{
cout<<v[i][j]<<" ";
}
cout<<v[i][j];
cout<<endl;
}
}
else
cout<<-1<<endl;
return 0;
}