二分法的习题,Day 10
#include<iostream> #include <algorithm> using namespace std; const int N=100000; int a[N],b[N],c[N]; int judge(int x) { for (int i=1;i<=N;i++) { for(int j=1;j<=N;j++) { for(int t=1;t<=N;t++) { if (a[i]==b[t]) {c[j]=t;break;} }break; } } sort(c,c+N); if(x<=c[1]) { return true; } else return false; } int main () { int n,T,H; cin>>T; while (T--) { cin>>n; H=2*n; int l=1,r=H; int ans=-1; for (int z=1;z<=H;z++) { cin>>a[z]; } while (l<=r) { int mid=(l+r)>>1; if(judge(mid)) { ans=mid; l=mid+1; } else r=mid-1; } cout<<ans<<endl; } return 0; }
我的覅一个函数不对,我应该去找第一个出现重复的数的位置,可是,怎么找呢?
感觉思路和第二个的例题蛮像?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include <algorithm> 3 using namespace std; 4 5 bool judge(int x,int a[],int n) 6 { 7 int b[n]; 8 for (int i;i<=n;i++) 9 { 10 b[i]=a[i]; 11 } 12 for (int i=1;i<=x;i++) 13 { 14 for(int j=2;j<=x;j++) 15 { 16 if(a[i]==b[j])return false; 17 } 18 } 19 return true; 20 } 21 22 int main () 23 { 24 int n,T,h; 25 cin>>T; 26 while (T--) 27 { 28 cin>>n; 29 h=2*n; 30 int a[h]; 31 int l=1,r=h; 32 int ans=-1; 33 for (int z=1;z<=h;z++) 34 { 35 cin>>a[z]; 36 } 37 while (l<=r) 38 { 39 int mid=(l+r)>>1; 40 if(judge(mid,a,h)) 41 { 42 ans=mid; 43 l=mid+1; 44 } 45 else r=mid-1; 46 } 47 cout<<ans/2<<endl; 48 } 49 return 0; 50 51 }
judge函数的意义在于判断x前的数组有木有重复的数 没有,就返回true 查询后面的一半 有 就返回false 查询前面的 一直找到第一个重复的数
这次的可以输出标答,但是超时了,可能是判断x前的数组有没有重复的用了两个FOR循环;;;;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 const int N=1e5+5; 4 int n,a[2*N],b[2*N]; 5 bool jugde(int mid) 6 { 7 int t=1; 8 for(int i=1;i<=2*n;i++) 9 { 10 if(a[i]<mid) b[t++]=a[i]; 11 } 12 for(int i=1;i<t;i+=2) 13 { 14 if(b[i]!=b[i+1]) return false; 15 } 16 return true; 17 } 18 int binary() 19 { 20 int l=1,r=n,ans=1; 21 while(l<=r) 22 { 23 int mid=(l+r)>>1; 24 if(jugde(mid)) 25 { 26 ans=mid; 27 l=mid+1; 28 } 29 else r=mid-1; 30 } 31 return ans; 32 } 33 int main() 34 { 35 int t; 36 cin>>t; 37 while(t--) 38 { 39 cin>>n; 40 for(int i=1;i<=2*n;i++) 41 cin>>a[i]; 42 cout<<binary()<<endl; 43 } 44 return 0; 45 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include <algorithm> 3 using namespace std; 4 const int N=100000+5; 5 int b[2*N],a[2*N]; 6 int n; 7 8 bool judge(int x) 9 { 10 int t=1; 11 for(int i=1;i<=2*n;i++) 12 { 13 if(a[i]<x) b[t++]=a[i]; 14 } 15 for(int i=1;i<=t;i+=2) 16 { 17 if(b[i]!=b[i+1]) return false; 18 } 19 return true; 20 } 21 22 int main () 23 { 24 int T; 25 cin>>T; 26 while (T--) 27 { 28 cin>>n; 29 int l=1,r=n; 30 int ans=1; 31 for (int z=1;z<=2*n;z++) 32 { 33 cin>>a[z]; 34 } 35 while (l<=r) 36 { 37 int mid=(l+r)>>1; 38 if(judge(mid)) 39 { 40 ans=mid; 41 l=mid+1; 42 } 43 else r=mid-1; 44 } 45 cout<<ans<<endl; 46 } 47 return 0; 48 49 }
咳咳,下面开始对标答的分析
1·思路和我不一样,虽然也是用第二题的模板,但是这个思路是把x之后的数列全部删掉,再看前面的数组能不能连起来,这样显然降低了复杂度,我之前一直在超时就是因为judge函数用了两个for 循环,让复杂度太高了,数据又大所以超时了
2·学到的一点,函数里面用到了数组a【】,不用再int judge(int i,int a[]),只要在外面开头定义一个全局变量,n也是
第二题:
课上例题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include <algorithm> 3 using namespace std; 4 5 bool judge(long long x,long long a[],long long n,long long s) 6 { 7 long long b[n],c[n]; 8 for (long long i=1;i<=n;i++) 9 { 10 b[i]=a[i]+i*x; 11 } 12 sort(b+1,b+n+1); 13 long long sum=0; 14 for (long long i=1;i<=x;i++) 15 { 16 sum+=b[i]; 17 } 18 if(sum<=s) 19 { 20 return true; 21 } 22 else return false; 23 } 24 25 int main () 26 { 27 long long n,T,s; 28 cin>>T; 29 while (T--) 30 { 31 cin>>n>>s; 32 long long a[n]; 33 long long l=1,r=n; 34 long long ans=-1; 35 for (long long z=1;z<=n;z++) 36 { 37 cin>>a[z]; 38 } 39 while (l<=r) 40 { 41 long long mid=(l+r)>>1; 42 if(judge(mid,a,n,s)) 43 { 44 ans=mid; 45 l=mid+1; 46 } 47 else r=mid-1; 48 } 49 cout<<ans<<endl; 50 } 51 return 0; 52 53 }
之要注意一下数字大小就好
第三题初步思路
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 long long a[100000]; 4 5 struct Node{ 6 long long L , R; 7 long long sum; 8 }Node[1000000]; 9 10 void pushup(long long i) 11 { 12 Node [i].sum=Node[i<<1].sum+Node[(i<<1)|1].sum; 13 } 14 15 void build(long long i,long long r) 16 { 17 Node[i].L=1; 18 Node[i].R=r; 19 Node[i].sum=0; 20 if(r==1) 21 { 22 Node[i].sum=a[1]; 23 return ; 24 } 25 long long mid=(1+r)>>1; 26 build (i<<1,mid); 27 build ((i<<1)|1,r); 28 pushup (i); 29 } 30 31 void judge(int x) 32 { 33 34 } 35 int main() 36 { 37 int T,N; 38 cin>>T; 39 int ans=-1; 40 while (T--) 41 { 42 cin>>N; 43 int l=1,r=N; 44 for (long long z=1;z<=N;z++) 45 { 46 cin>>a[z]; 47 } 48 while (l<=r) 49 { 50 long long mid=(l+r)>>1; 51 if(judge(mid)) 52 { 53 ans=mid; 54 l=mid+1; 55 } 56 else r=mid-1; 57 } 58 cout<<ans<<endl; 59 } 60 }