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的位置。