HDU - 5178 思维多种解答(大佬们如何巧妙的解题)

HDU - 5178 

题意:输入数组a和k,求多少对a,b,(a<b使得|x[b]x[a]|k?

普普通通版本:暴力解答(超时严重)

1 for(int i=0;i<n;i++){
2         for(j=0;j<i;j++){
3         if(abs(a[i]-a[j])<=k) 
4         ans++;
5         }
6 }

各种大佬版本:属于大佬们的show time

one.尺取法----202ms

 1 # include <stdio.h>
 2 # include <algorithm>
 3 using namespace std;
 4 int a[100001];
 5 int main()
 6 {
 7     int n, k, t;
 8     scanf("%d",&t);
 9     while(t--)
10     {
11         scanf("%d%d",&n,&k);
12         long long ans = 0;
13         for(int i=0; i<n; ++i)
14             scanf("%d",&a[i]);
15         sort(a, a+n);
16         for(int l=0,r=0; l<n; ++l)
17         {
18             while(r+1<n && a[r+1]-a[l]<=k) ++r;
19             ans += r-l;
20         }
21         printf("%lld\n",ans);
22     }
23     return 0;
24 }

two.二分upper_bound法-----234ms

 1 # include <stdio.h>
 2 # include <algorithm>
 3 using namespace std;
 4 int a[100001];
 5 int main()
 6 {
 7     int n, k, t;
 8     scanf("%d",&t);
 9     while(t--)
10     {
11         scanf("%d%d",&n,&k);
12         long long ans = 0;
13         for(int i=0; i<n; ++i)
14             scanf("%d",&a[i]);
15         sort(a, a+n);
16         for(int i=0; i<n-1; ++i)
17         {
18             int pos = upper_bound(a+i,a+n, a[i]+k)-a;
19             ans += pos - i - 1;
20         }
21         printf("%lld\n",ans);
22     }
23     return 0;
24 }

three.聪明法---202ms

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 #define N 100006
 5 #define ll long long 
 6 int n,k;
 7 int a[N];
 8 int main()
 9 {
10     int t;
11     scanf("%d",&t);
12     while(t--)
13     {
14         scanf("%d%d",&n,&k);
15         for(int i=0;i<n;i++) 
16         scanf("%d",&a[i]);
17         sort(a,a+n);
18         ll ans=0;
19         int tmp=0;
20         for(int i=0;i<n;i++)
21         {
22             while(abs(a[i]-a[tmp])<=k && tmp<n)//循环 
23             tmp++;
24             ans+=tmp-i-1;
25         }
26         printf("%I64d\n",ans);
27     }
28     return 0;
29 }

four.二分法

 1 #include<cstdio>
 2 #include<algorithm>
 3 //需要注意的是数据量大,用long long 类型
 4 typedef long long ll;
 5 int n;
 6 ll k;
 7 ll a[100001];
 8 using namespace std;
 9 void solve(){
10     ll ans = 0;
11     for(int i = 0; i < n; i++){//先遍历每个元素,尝试找到第一个满足条件的元素
12         ll l, r, mid;
13         l = i;
14         r = n - 1;
15         while(r >= l){
16             mid = (l + r)/2;
17             if(a[mid] - a[i] > k){
18                 r = mid - 1;//
19             }
20             else{
21                 l = mid + 1;
22             }
23         }
24         ans += r - i;
25     }
26     printf("%I64d\n", ans);
27 }
28  
29 int main(){
30     int t;
31     scanf("%d", &t);
32     while(t--){
33         scanf("%I64d%I64d", &n, &k);
34         for(int i = 0; i < n; i++){
35             scanf("%I64d", &a[i]);
36         }
37         sort(a, a + n);
38         solve();
39     }
40 }

心得:人生好苦,希望锻炼出健康的体魄和聪明的头脑!!!

猜你喜欢

转载自www.cnblogs.com/Aiahtwo/p/10832195.html