codevs1217 借教室 题解
题意
/中文题惯例不翻译
笺释
这道题确实不好过,内存方面和时间方面要求都相当严格呢。
思路的话无非二分人数,最小第一个人就要取消掉,最大的话m个人都能满足,并且第i个人能满足的话,i个人之前的一定也满足(否则在之前就取消掉了)。
但是如何确定第i个人能否满足呢,这道题用到的是差分数组的方法,
int check(int x)
{
int ans=0;
//pre[i]:差分数组 里面存的是能让ans代表第i天所需教室的数字
for(int i=1;i<=n;i++)
{
pre[i]=0;
}
for(int i=1;i<=x;i++)
{
pre[s[i]]+=d[i];
pre[t[i]+1]-=d[i];
}
for(int i=1;i<=n;i++)
{
ans+=pre[i];
if(ans>r[i])
{
return 0;
}
}
return 1;
}
具体想表达的感觉就已经完全被表达出来了,不知道能不能说明白呢,时常为此感到困惑。
互相理解果然是需要双方的共同努力才行的呢,不过对于我来说,也确实存在着诸多表达方面的问题,不过自己能否理解自己呢,我想,总是要让自己多多少少或是完完全全地理解自己才行的。
完整代码
#include<bits/stdc++.h>
#define MAXN 1000005
using namespace std;
int n,m;
int r[MAXN];
int d[MAXN],s[MAXN],t[MAXN];
int pre[MAXN];
int check(int x)
{
int ans=0;
//pre[i]:差分前缀数组 里面存的是能让ans代表第i天所需教室的数字
for(int i=1;i<=n;i++)
{
pre[i]=0;
}
for(int i=1;i<=x;i++)
{
pre[s[i]]+=d[i];
pre[t[i]+1]-=d[i];
}
for(int i=1;i<=n;i++)
{
ans+=pre[i];
// printf("%d %d
",ans,i);
if(ans>r[i])
{
return 0;
}
}
return 1;
}
int solve()
{
int l=1;
int r=m;
while(l<=r)
{
//printf("%d %d
",l,r);
int mid=(l+r)>>1;
if(check(mid))
{
l=mid+1;
}
else
{
r=mid-1;
}
}
if(l<=m)
{
printf("-1
%d
",l);
}
else
{
printf("0
");
}
return 0;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&r[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&d[i],&s[i],&t[i]);
}
solve();
}