BestCoder3 1001 Task schedule(hdu 4907) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4907

题目意思:给出工作表上的 n 个任务,第 i 个任务需要 ti 这么长的时间(持续时间是ti ~ ti+1)来完成。有m 个询问,每个询问是一个数字q,表示q 时间上有一个非 n 个任务之外的任务请求。机器是按照工作表的任务时间来执行的,如果有空档时间,它会执行工作表之外的任务请求。

直接做,果断超时!1e5 * 2e5 !!!(m次询问+q次遍历 的最坏情况)

二分解决之~~~~一开始我不是只存储空闲时间啦,我还把工作表上要处理的n 个任务的时间都存在一起,导致写的二分不三不四啊~~~~= =

二分思想其实好容易理解,真正运用起来还是第一次啊~~~好好纪念纪念 ^_^

(1)这个是参考别人的,不过时间稍微用得有点多

Exe time :  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6
 7 const int maxn = 2e5;
 8 int a[maxn], b[maxn];
 9
10 int main()
11 {
12     int T, n, m, ti, query;
13     while (scanf("%d", &T) != EOF)
14     {
15         while (T--)
16         {
17             memset(a, 0, sizeof(a));
18             memset(b, 0, sizeof(b));
19             scanf("%d%d", &n, &m);
20             for (int i = 0; i < n; i++)
21             {
22                 scanf("%d", &ti);
23                 a[ti] = 1;
24             }
25             int len = 0;
26             for (int i = 1; i <= maxn; i++)
27             {
28                 if (!a[i])
29                     b[len++] = i;  // 把空余时间存储起来
30             }
31             for (int i = 0; i < m; i++)
32             {
33                 scanf("%d", &query);
34                 if (!a[query])
35                     printf("%d\n", query);
36                 else
37                 {
38                     int flag = 0;
39                     int l = 0, r = len-1;
40                     while (l <= r)
41                     {
42                         int mid = (l+r)/2;
43                         if (b[mid] == query)
44                         {
45                             printf("%d\n", b[mid]);
46                             flag = 1;
47                             break;
48                         }
49                         else if (b[mid] < query)
50                             l = mid+1;
51                         else if (b[mid] > query)
52                             r = mid-1;
53                     }
54                     if (!flag)
55                         printf("%d\n", b[l]);
56                 }
57             }
58         }
59     }
60     return 0;
61 }

(2) 我的改良版本(其实不需要把maxn,也就是2e5 个所有空闲时间都存起来啦,只要把原来n个任务中最大的时间,再+1的那个时间存起来即可!!!)

所以maxi + 1 就是这个意思啦。

Exe  time :    

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6
 7 const int maxn = 2e5;
 8 int vis[maxn], b[maxn];
 9
10 int main()
11 {
12     int T, n, m, t, q;
13     while (scanf("%d", &T) != EOF)
14     {
15         while (T--)
16         {
17             memset(vis, 0, sizeof(vis));
18             scanf("%d%d", &n, &m);
19             int maxi = 1;
20             for (int i = 1; i <= n; i++)
21             {
22                 scanf("%d", &t);
23                 maxi = max(maxi, t);
24                 vis[t] = 1;
25             }
26             int len = 0;
27             for (int i = 1; i <= maxi+1; i++)  // maxi+1表示n个任务中花费时间最长为maxi,假设遇到一个maxi/maxi+1的任务,那么这个任务执行时间就是maxi+1
28             {
29                 if (!vis[i])
30                     b[len++] = i;
31             }
32             while (m--)
33             {
34                 scanf("%d", &q);
35                 if (!vis[q])
36                     printf("%d\n", q);
37                 else
38                 {
39                     int l = 0, r = len-1;
40                     int flag = 0;
41                     while (l <= r)
42                     {
43                         int mid = (l+r)>>1;
44                         if (b[mid] == q)
45                         {
46                             flag = 1;
47                             printf("%d\n", b[mid]);
48                             break;
49                         }
50                         else if (b[mid] > q)
51                             r = mid-1;
52                         else if (b[mid] < q)
53                             l = mid+1;
54                     }
55                     if (!flag)
56                         printf("%d\n", b[l]);
57                 }
58             }
59         }
60     }
61     return 0;
62 }
时间: 2024-12-30 00:02:06

BestCoder3 1001 Task schedule(hdu 4907) 解题报告的相关文章

BestCoder3 1002 BestCoder Sequence(hdu 4908) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4908 题目意思:给出 一个从1~N 的排列你和指定这个排列中的一个中位数m,从这个排列中找出长度为奇数,中位数是m的子序列有多少个. 我的做法被discuss 中的测试数据一下子就否定了. 这个是别人的做法,暂时留下来,有些地方还没真正弄懂,应该是缺了部分的知识没有学到... 留着先: (1)http://blog.csdn.net/hcbbt/article/details/38377815 (2

BestCoder12 1001.So easy(hdu 5058) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5058 (格式有点问题,为了方便阅读---整个复制下来吧) 题目意思:给出两个长度都为 n 的集合你,问这两个集合是否相等. 其实思路非常容易想到,就是去重后判断嘛---我用到了set 来做.不过有个小细节!!! 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstr

hdu 2112 HDU Today 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 题目意思:又是求最短路的,不过结合埋字符串来考查. 受之前1004 Let the Balloon Rise 学到用map 的解法做之后,有点蠢蠢欲动,当时见到要用字典树做有点吓坏了(之前看过下,非一般难理解,所以暂时放下了).于是,死就死吧,硬住头皮用map做,反反复复修改终于过了. 首先是memory limit exceeded,因为无读清题目意思,直接开10000 * 10000的数组

BestCoder10 1001 Revenge of GCD(hdu 5019) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5019 题目意思:给出 X 和 Y,求出 第 K 个 X 和 Y 的最大公约数. 例如8 16,它们的公约数依次为1 2 4 8,那么第 3 个 GCD(X, Y) = 2,也就是从后往前数第3个公共因子. TLE思路:求出 X 的所有因子(从小到大开始存储),再从后往前枚举这些因子,检查是否也为 Y 的因子,统计到第 K 个数就是答案了......以为可以顺利通过,原来数据量还是非常大滴!!! 正确

BestCoder10 1001 Revenge of Fibonacci(hdu 5018) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5018 题目意思:给出在 new Fibonacci 中最先的两个数 A 和 B(也就是f[1] = A, f[2] = B),通过这条式子f[n] = f[n-1] + f[n-2],问 C 是否在这条 new Fibonacci sequence 内.(1 <= A, B, C <= 1 000 000 000) 首先,要想到 C 有可能是 A 或者 B,这种情况也是属于在这个序列范围内的. 还

BestCoder24 1001.Sum Sum Sum(hdu 5150) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5150 题目意思:就是直接求素数. 不过 n = 1,也属于答案范围!!只能说,一失足成千古恨啊----- 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 1

BestCoder18 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5108 题目意思:给出一个数正整数 N,N <= 1e9,现在需要找出一个最少的正整数 M,使得 N/M 是素数.如果找不到就输出0. 一开始有想过将所有 <= 1e9 的素数求出来的,不过绝对超时就放弃了:然后就开始从题目中挖掘简便的处理方法.受到求素数的方法启发,枚举的因子 i 如果在 i * i <= N 之内都没有找到符合条件的素数,那么那些 > N 的因子就更不可能了.于是时间

BestCoder8 1001.Summary(hdu 4989) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4989 题目意思:给出 n 个数,然后将这些数两两相加,得到 n*(n-1) /2 对和,把重复的和去掉,最后相加起来. 用STL中的set可以好方便的做出来,因为 insert 的时候它会自动去除重复的.记得要用 long long 或 int64,因为 -1000000000 <= ai <= 1000000000 ! 1 #include <iostream> 2 #include

BestCoder17 1001.Chessboard(hdu 5100) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5100 题目意思:有一个 n * n 的棋盘,需要用 k * 1 的瓷砖去覆盖,问最大覆盖面积是多少. 比赛时不会做............. hdu 题解: 首先,若n<k,则棋盘连一个1×k的矩形都放不下,输出0. 我们只需要考虑n≥k的情况.将棋盘类似于黑白染色,按(i+j)模k划分等价类,给每个格子标一个号. 标号之后,会注意到每条从左下到右上的斜线数字都是相同的,那么对于s×s的格子,其内部