G - 考试
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
期末考试快到了,qdu的考试周一共有n天,你要在这n天里考m门课,这m门课从1到m编号。
我们知道这n天内的每一天可以考哪一门课,当然,也有可能有一天不能考试。 每天只能考一次试。
你每天可以做三件事,考试、复习、或者休息。
每门课都有一个需要复习的天数,比如第i门课需要复习ai天,只有当你总共复习了ai天的第i门课,你才能在考试中通过这第i门课。当然,你也不用非得连续几天都复习一门课,可以穿插着复习,只要最后的天数满足就可以了。
为了尽早回家,你想计算出考完这m门课最少需要多少天?当然每门课都要考通过。要是怎么也不能全部通过,那就输出-1。
还是不太理解题意的话,就去看hint。
Input
第一行两个整数 n 和 m (1 ≤ n, m ≤ 105) — n天,m门课。
第二行n个整数 d1, d2, ..., dn (0 ≤ di ≤ m), di 表示这一天可以考第di 门课。如果 di 为 0,那么这一天只能复习或休息,不能考试。
第三行m个整数 a1, a2, ..., am (1 ≤ ai ≤ 105), ai 表示通过第i门课至少要复习准备这门课多少天。
Output
输出一个整数。 — 最少多少天可以通过全部的考试。 如果不可能输出-1。
Sample Input
Input1:
7 2
0 1 0 2 1 0 2
2 1
Input2:
10 3
0 0 1 2 3 0 2 0 1 2
1 1 4
Input3:
5 1
1 1 1 1 1
5
Sample Output
Output1:
5
Output2:
9
Output3:
-1
Hint
第一个样例: 第一天和第二天复习科目 1 然后在第五天通过, 第三天复习科目2然后在第四天通过。
第二个样例: 前四天复习科目 3 然后在第五天通过。第六天复习科目 2 然后在第七天通过。第八天复习科目1然后在第九天通过。
第三个样例:时间不够根本通过不了考试。
#include<stdio.h>
#include<string.h>
#define N 100010
int m,n;
int d[N];
int a[N];
int book[N];
int check(int x)
{
memset(book,0,sizeof(book));
int i,j,sum=0;
for(i=x;i>=1;i--)
{
if(d[i]!=0&&book[d[i]]==0)
{
book[d[i]]=1;
sum=sum+a[d[i]];
}
else if(sum!=0)
{
sum--;
}
}
for(j=1;j<=m;j++)
{
if(book[j]==0)
return 0;
}
if(sum!=0)
return 0;
return 1;
}
int main()
{
int i,j,l,r,mid;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&d[i]);
for(i=1;i<=m;i++)
scanf("%d",&a[i]);
l=1;r=n;
while(l<r)
{
mid=(l+r)/2;
if(check(mid)==0)//复习天数不够用,mid要增大
l=mid+1;
else
r=mid;
}
if(check(l)==1)
printf("%d",l);
else
printf("-1");
return 0;
}