ZJNU 1542 - 三角形(续)--中高级

从小到大排序后

先固定一遍,另外两边递增查找

即固定 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 }

猜你喜欢

转载自www.cnblogs.com/stelayuri/p/12236196.html