• 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", b[l]);
    57                 }
    58             }
    59         }
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    Xsheel远程链接ECS,Xftp上传文件到ECS
    javaEE 转发 和 重定向
    android 快速开发框架
    java/Android String.split 字符串分割
    Android 选择本地图片的demo
    docker swarm 集群进入某节点容器失败的原因及解决方法
    nginx中有关 root 和 alias的主要区别
    docker研究-2
    docker研究-1
    mysql数据库表操作-表的主键索引和普通索引
  • 原文地址:https://www.cnblogs.com/windysai/p/3930708.html
Copyright © 2020-2023  润新知