从小到大排序后
先固定一遍,另外两边递增查找
即固定 i,j=i+1,k=j+1
然后让k递增到 a[i]+a[j]<=a[k] 时
此时不能凑成一个三角形
答案增加 k-1-j 组
此时不需要重置 k=j+1
因为 j++ 后 a[j] 会变大
那么在 j~k 之间的所有木棍长度均能再次满足这种 ij 组合
此时只需要把前一个状态的 k 继续往后查找即可
如果 k 查找到了最后,因为i固定,可得 j 不断向后移动,最后能增加的组合有 (n-j)*(n-j-1)/2 组,结束 j 循环,i++
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 int ar[2010]; 5 int main() 6 { 7 ios::sync_with_stdio(0); 8 cin.tie(0);cout.tie(0); 9 int T,n,i,j,k,ans,d; 10 cin>>T; 11 while(T--) 12 { 13 cin>>n; 14 for(i=1;i<=n;i++) 15 cin>>ar[i]; 16 sort(ar+1,ar+n+1); 17 ans=0; 18 for(i=1;i<=n-2;i++) 19 { 20 k=i+2; 21 for(j=i+1;j<=n-1;j++) 22 { 23 d=ar[i]+ar[j]; 24 while(k<=n&&d>ar[k]) 25 k++; 26 ans+=k-1-j; 27 if(k>n) 28 { 29 ans+=(n-j)*(n-j-1)/2; 30 break; 31 } 32 } 33 } 34 cout<<ans<<endl; 35 } 36 37 return 0; 38 }