2017.12.24(查找最接近元素,全排列等)
2017.12.24
贪心,分治综合习题(2)
1.查找最接近元素
思路:由题可知,n<=100000,m<=10000,如果每一个m都把这个非降序序列扫一遍的话,那么时间复杂的将要到达1010那么多,明显不合题意;所以,只能用二分查找来优化时间复杂度。
核心代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int main(){ 5 int m,n,k,num[100001]; 6 int i,j; 7 scanf("%d",&n); 8 for(i=1;i<=n;i++) 9 scanf("%d",&num[i]); 10 scanf("%d",&m); 11 for(i=1;i<=m;i++){ 12 scanf("%d",&k); 13 int left=1,right=n,mid,bz=0; 14 while(left<right-1){ 15 bz=0; 16 mid=(left+right)/2; 17 if(k==num[mid]){ 18 printf("%d\n",k); 19 bz=1; 20 break; 21 } 22 else if(k>num[mid]) 23 left=mid; 24 else if(k<num[mid]) 25 right=mid; 26 } 27 if(num[right]-k<k-num[left]&&bz==0){ 28 printf("%d\n",num[right]); 29 } 30 else if(num[right]-k>=k-num[left]&&bz==0){ 31 printf("%d\n",num[left]); 32 } 33 } 34 return 0; 35 }
状态:AC
2.全排列
思路:这个题目的数据范围不大,K<=6,所以可以使用没有任何优化的搜索。题目保证输入的字符串是已经排好序的,所以可以就可以把输入的字符串作为一个有序序列来使用。
核心代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 char letter[1000],answer[1000]; 5 int book[1000]={0},l; 6 void print(){ 7 for(int i=0;i<l;i++) 8 printf("%c",answer[i]); 9 printf("\n"); 10 return; 11 } 12 void search(int n){ 13 int i,j; 14 if(n==l){ 15 print(); 16 return; 17 } 18 for(i=0;i<l;i++){ 19 if(book[i]==0){ 20 book[i]=1; 21 answer[n]=letter[i]; 22 search(n+1); 23 book[i]=0; 24 } 25 } 26 return; 27 } 28 int main(){ 29 gets(letter); 30 l=strlen(letter); 31 search(0); 32 return 0; 33 }
状态:AC
3.最大子段和
思路:详见2017.12.25 的<详解 最大子段和>
核心代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 int main(){ 5 int n,max=-2147483645,num,sum=0; 6 scanf("%d",&n); 7 for(int i=1;i<=n;i++){ 8 scanf("%d",&num); 9 sum+=num; 10 if(sum>max)max=sum; 11 if(sum<0)sum=0; 12 } 13 printf("%d",max); 14 return 0; 15 }
状态:AC