2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest I. Distance
链接:https://codeforces.com/gym/102028/problem/I
题意:数轴上有n个点,相邻两点间距离已知,取其中k点,求k点中每一对点距离和最大值,k分别取1,2,3,...,n
思路:k=i时,距离和为k=i-1时的距离和加上新选取的点与之前所取的点间距离和,所以每次只需要取最左或最右即可,如下图
序号表示选取的顺序
可以发现k为奇数时,新选取的点与其他点间距离和为子段的长度,如图中k=5时,总距离为k=4时的总距离加上1,2间距+3,4间距
k为偶数时,新选取的点与其他点间距离和为配对的两点间距离,如图中k=6时,总距离为k=5时的总距离加上1,2间距+3,4间距+5,6间距
用数组a保存第一个点到该点的距离
k取i时,可以发现规律:若i为奇数,总距离为i-1时的距离加上(a[2]-a[1])+...+(a[i-1]-a[i-2])
若i为偶数,总距离为i-1时的距离加上(a[2]-a[1])+...+(a[i]-a[i-1])
以下是代码:
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll M = ll(1e5)*2 + 5; 4 using namespace std; 5 ll a[M]; 6 signed main() 7 { 8 ll t; scanf("%I64d", &t); 9 for(ll c=1;c<=t;c++) 10 { 11 if (c != 1) printf("\n"); 12 ll n; scanf("%I64d", &n); 13 //memset(a, 0, M * sizeof(a)); 14 for (ll i = 2; i <= n; i++) 15 { 16 ll x; scanf("%I64d", &x); 17 a[i] = a[i - 1] + x; 18 } 19 ll ans = 0,tem=0; 20 ll l = 0, r = n + 1; 21 for (ll i = 1; i <= n; i++) 22 { 23 if (i & 1) 24 { 25 l++; 26 ans += tem; 27 } 28 else 29 { 30 r--; 31 tem += a[r] - a[l]; 32 ans += tem; 33 } 34 if (i != 1) printf(" "); 35 printf("%I64d", ans); 36 } 37 } 38 return 0; 39 }
备注:由于用cin,cout会超时,就改为scanf和printf
————————————————
心里有光,哪儿都美
心里有光,哪儿都美