CodeForce-732D. Exams-二分

 http://codeforces.com/problemset/problem/732/D

直接二分答案,check能否在x天内考完。

注意:二分边界,可以根据输入,求出能够复习的天数sum,考试天数M,因此 L = sum+M 否则超时

   自己。puts("-1")记得return;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 int ed[111111];//Eaxm day
 6 int nt[111111];//Need review time
 7 int dead[111111];// Deadline - the Last Exam day
 8 int inx[111111]; // if in the dead[]
 9 int N,M;
10 bool check(int x)
11 {
12     memset(inx,0,sizeof(inx));
13     int cnt = 0;
14     //找出每门课程在前x天 最后的考试时间
15     for (int i = 1; i <= x ; i++)
16     {
17         if (ed[i]!=0)
18         {
19             if (inx[ed[i]]==0) cnt++;
20               else  dead[ inx[ed[i]] ] = 0;
21             dead[i] = ed[i];
22             inx[ed[i]] = i;
23         }
24         else dead[i] = 0;
25     }
26     if ( cnt != M ) return false;
27     long long ht = 0 , ut = 0 ;
28     //扫一边1--x,对于每天i,拥有的复习时间ht。和需要的复习时间ut 始终应保持 ht >= ut
29     for (int i = 1; i <= x ; i++ )
30     {
31         if (dead[i] == 0) ht++;
32         else
33         {
34             ut += nt[ dead[i] ] ;
35         }
36         if (ht < ut) return false;
37     }
38     return true;
39 }
40 int main()
41 {
42     //freopen("in.txt","r",stdin);
43     scanf("%d%d",&N,&M);
44     int sum = 0;
45     int   flag = 1;
46     for (int i = 1; i<=N; i++)
47     {
48         scanf("%d",&ed[i]);
49     }
50     for (int i = 1 ; i<= M; i++)
51     {
52         scanf("%d",&nt[i]);
53         sum+=nt[i];
54         if (sum > N-M) flag = 0;
55     }
56     if (flag == 0) {puts("-1");return 0;}
57     int l = M + sum;
58     int r = N;
59     int ans = -1;
60     while (l<=r)
61     {
62         int mid = ( l + r ) / 2 ;
63         if (check(mid))
64         {
65             r = mid - 1;
66             ans = mid;
67         }
68         else l = l + 1;
69     }
70     cout << ans <<endl;
71 }

补充一份just_soso学长代码,用queue实现check()函数.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define fst first
 4 #define snd second
 5 typedef long long ll;
 6 typedef pair<ll, ll> pll;
 7 const int maxn=100005;
 8 ll n, m, d[maxn], a[maxn], sum;
 9 stack<pll> day;
10 bool vis[maxn];
11 bool check(ll mid) {
12     memset(vis, 0, sizeof vis);
13     vis[0]=true;
14     while (!day.empty())
15         day.pop();
16     int cnt=0;
17     for (int i=mid; i>=1; --i) {
18         if (vis[d[i]])
19             continue;
20         vis[d[i]]=true;
21         day.push(pll(a[d[i]], i));
22         ++cnt;
23     }
24     if (cnt<m)
25         return false;
26     ll tmp=0;
27     while (!day.empty()) {
28         pll t=day.top();
29         day.pop();
30         tmp+=t.fst+1LL;
31         if (tmp>t.snd)
32             return false;
33     }
34     return true;
35 }
36 int main()
37 {
38     //freopen("in.txt", "r", stdin);
39     while (scanf("%I64d%I64d", &n, &m)==2) {
40         sum=0;
41         for (int i=1; i<=n; ++i)
42             scanf("%I64d", &d[i]);
43         for (int i=1; i<=m; ++i) {
44             scanf("%I64d", &a[i]);
45             sum+=a[i];
46         }
47         ll left=m+sum, right=n, res=-1;
48         while (left<=right) {
49             ll mid=(left+right)>>1;
50             bool flag=check(mid);
51             if (flag) {
52                 res=mid;
53                 right=mid-1;
54             } else
55                 left=mid+1;
56         }
57         printf("%I64d
", res);
58     }
59     return 0;
60 }
just_soso
原文地址:https://www.cnblogs.com/HITLJR/p/5974299.html