侧边栏

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

 

posted @ 2019-02-13 23:47  晴人  阅读(408)  评论(0编辑  收藏  举报