标签:set bsp line problem force syntax comm 天都 访问
用力戳我直达原题:D - Exams
题意:
有N天和M门课程。
接下来给你N天的行为,0表示这一天只能预习,[1,m]表示这一天可以考这门课(当然这一天你也可以选择不考或者预习)。
接下来给你M个数cost[i],代表第i门课需要预习cost[i]天才能PASS。
求从第一天起算,最少需要几天才能PASS所有功课,如果N天都PASS不了,则输出-1。
做法:
1.先判断用N天能否PASS,不能就输出-1。
2.low = m, high = n。求左界。
3-1 judge的时候,一门课肯定越慢考越容易通过,所以从mid开始找,第一次遇到的功课标记vis[day[i]]。
3-2 如果day[i]等于0或者day[i]已经访问过了,也就是说这一天能用来复习,sum++;
3-3 如果sum >= 预习所需要的总时间sum_cost,且所有课程都有安排考试,说明时间充裕,返回true。
3-4 第一天肯定只能拿来复习不能拿来考试,所以sum初始化为1,遍历从 mid -> 2。
3-5 从mid开始找到第一个不是0的数,因为这些天的复习是无效的,后面无考试了。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <bits/stdc++.h>usingnamespacestd;intday[100100];intsum_cost = 0;boolvis[100100];intn, m, x;booljudge(intmid) {    memset(vis, false, sizeof(vis));    while(day[mid] == 0) mid--;    intsum = 1;  //累加预习时间    inttot = 0;  //累加安排考试科目数    for(inti = mid; i >= 2; i--) {        intcur = day[i];        if(vis[cur] || cur == 0) sum++;        elsetot++, vis[cur] = true;    }    return(sum >= sum_cost && tot == m);}intmain() {    scanf("%d%d", &n, &m);    for(inti = 1; i <= n; i++) scanf("%d", day+i);    for(inti = 1; i <= m; i++) scanf("%d", &x), sum_cost += x;  //累计最终需要多少天    if(judge(n) == false) {        puts("-1");        return0;    }    intlow = m, high = n;    while(low < high) {        intmid = low + high >> 1;        if(judge(mid)) high = mid;        elselow = mid + 1;    }    printf("%d\n", high);} | 
标签:set bsp line problem force syntax comm 天都 访问
原文地址:http://www.cnblogs.com/bestwzh/p/6731051.html