BestCoder Round #3HDU 4907

1. HDU 4907:http://acm.hdu.edu.cn/showproblem.php?pid=4907

  中文题我就不说题意了,直接说解题思路吧!

  ① 第一种思路就是我比赛时的思路,将a数组先全部清为零,当输入机器在ti时间执行第i个任务时,将a[ti]置为1,开始输入q(表示在q时间有一个工作表之外的任务请求)写一个循环,让a数组从a[q]开始循环,直到找到a[J]为0,输出j。这种方法时间超限了,但是在输入q之前先预处理,打一个表就不会超时了。

  附上代码:

    

 1 #include<stdio.h>
 2 #include<string.h>
 3 int t[200010],s[200010];
 4 int main()
 5 {
 6     int T,m,n,i,j,k,a;
 7     scanf("%d",&T);
 8     while(T--)
 9     {
10         scanf("%d%d",&m,&n);
11         memset(t,0,sizeof(t));
12         for(i=1; i<=m; i++)
13         {
14             scanf("%d",&a);
15             t[a]=1;
16         }
17         memset(s,0,sizeof(s));
18         k=1;
19         for(i=1; i<=200000; i++)
20             if(t[i]==0)
21             {
22                 for(j=k; j<=i; j++)
23                     s[j]=i;
24                 k=i+1;
25             }
26         while(n--)
27         {
28             scanf("%d",&a);
29             printf("%d
",s[a]);
30         }
31     }
32     return 0;
33 }

   ②第二种思路是二分法,输入a[],后排下序,然后记录每个数字出现的位置,对于询问q,如果q不存在直接输出q,

如果q存在,假设q所在的位置为pos,那么二分【pos,n】,二分判断的依据是如果mid-p==a[mid]-a[p],那么left=mid+1,否则right=mid-1.

附上代码:

    

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<string.h>
 5 using namespace std;
 6 #define maxn 100010
 7 int a[maxn];
 8 int main()
 9 {
10     int T,i;
11     scanf("%d",&T);
12     while(T--)
13     {
14         int n,m;
15         scanf("%d%d",&n,&m);
16         for(i=0; i<n; i++)
17             scanf("%d",&a[i]);
18         sort(a,a+n);
19         while(m--)
20         {
21             int q;
22             scanf("%d",&q);
23             int pos=int(lower_bound(a,a+n,q)-a);
24             if(pos==n||a[pos]!=q)
25                 printf("%d
",q);
26             else
27             {
28                 int left=pos+1,right=n;
29                 while(left<right)
30                 {
31                     int mid=(left+right)>>1;
32                     if(a[mid]-q==mid-pos)
33                         left=mid+1;
34                     else
35                         right=mid;
36                 }
37                  printf("%d
",a[left-1]+1);
38             }
39         }
40     }
41     return 0;
42 }

后记:

    函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置。

  

————Anonymous.PJQ
原文地址:https://www.cnblogs.com/PJQOOO/p/3890473.html