这一题当然不能去枚举n,而是要去扩展构造.
假设当前区间为[L,R].我们要将这个区间扩展为[0,?](当然是在可行的情况下)
由于被扩展出的区间与当前区间的长度最多相差一(而且在左边的区间长度不小于右边,可证),所以有四种方向扩展(设区间长度为len):
1.由区间[L,R]扩展出[L-len-1,L-1],区间变为[L-len-1,R];
2.由区间[L,R]扩展出[L-len,L-1],区间变为[L-len,R];
3.由区间[L,R]扩展出[R+1,R+len],区间变为[L,R+len];
4.由区间[L,R]扩展出[R+1,R+len-1],区间变为[L,R+len-1];
当然,我们还要加一点剪枝,然后就A了,总复杂度应该是4*log2(R-L+1),稳.
1 #include<cstdio> 2 #include<iostream> 3 int L,R,limitn,ans; 4 using namespace std; 5 void B(int L,int R){ 6 if (L<0||R>=ans||L>R) return; 7 if (L==0){ans=R; return;} 8 int len=R-L+1; if (R-L+1>L) return; 9 B(L-len,R); B(L-len-1,R); B(L,R+len-1); B(L,R+len); 10 } 11 int main(){ 12 int T; scanf("%d",&T); 13 for (; T; T--){ 14 cin>>L>>R>>limitn,ans=limitn+1; 15 B(L,R); if (ans==limitn+1) ans=-1; 16 printf("%d\n",ans); 17 } 18 return 0; 19 }
时间: 2024-10-14 05:21:21