题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5163
题目意思:有 n 个车站,给出相邻两个车站的距离,即车站 i 和车站 i+1 的距离为 di (1≤ i <n)。然后是 m 个人从他的出发点到他想去的终点(都是车站),约定轮到处理第 i 个人的时候,车站的出发点满足:((i-1) mod n) + 1 ,假设车每走一个单位的距离花费一个单位的时间,车开始的时候是从左到右开的。如果车走到最右的车站即车站 n 会调头,此时方向为从右到左开;如果车走到最左即车站 1,方向转为从左到右开。求出每个人从他出发点到终点需要的最少时间是多少。注意,这个人的出发点不一定和车的出发点相同,此时他要候车,候车时间也计算在内。
赛中过于浮躁,来不及写完......
赛后各种 wa,各种wa.......
思路是对的,就是分六种情况,通过画图,写出公式
1. s≤x<y, 2. x<s<y, 3. x<y≤s, 4. s≤y<x, 5. y<s<x, 6. y<x≤s
通过公式的化简,发现有些情况是可以合并的。当 x < y,只要分成两种情况即可(st 即 s ): s <= x(ans = sum[y]-sum[st];) 和 x < s < y, s > y(ans = 2*sum[n] + sum[y] - sum[st];); 当 x > y,公式只有一条(前提是先交换 x , y 的值,保证x, y的大小,方便sum[]的处理):ans = 2*sum[n] - sum[x] - sum[st];
(sum[y]: 从第一个站到第 y 个站的距离,这个是求解时的优化,如果一个一个距离加,会TLE!还有就是由于求解的时候数据可能很大,要用 long long )
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 typedef __int64 ll; 8 const int maxn = 1e5 + 5; 9 ll d, sum[maxn]; 10 11 int main() 12 { 13 int n, m, t; 14 while (scanf("%d", &t) != EOF) { 15 while (t--) { 16 scanf("%d%d", &n, &m); 17 memset(sum, 0, sizeof(sum)); 18 for (int i = 1; i < n; i++) { 19 scanf("%lld", &d); 20 sum[i+1] = d + sum[i]; 21 } 22 int x, y; 23 for (int i = 1; i <= m; i++) { 24 scanf("%d%d", &x, &y); 25 int st = (i-1)%n + 1; 26 ll ans = 0; 27 if (x < y) { // 左--> 右 28 if (st <= x) // s<=x<y 29 ans = sum[y]-sum[st]; 30 else 31 ans = 2*sum[n] + sum[y] - sum[st]; // x<s<y, x<y<s 32 } 33 // 右--> 左 34 else { // x<y, 题目说x!=y 35 swap(x, y); 36 ans = 2*sum[n] - sum[x] - sum[st]; // s<y<x, y<s<x, y<x<s 37 } 38 printf("%I64d\n", ans); 39 } 40 } 41 } 42 return 0; 43 }
原始版(比较详细而且很长,未合并公式前),原来没有覆盖所有情况呀,不过已经改好了, 痛苦改 bug 路 。呜呜呜呜呜呜~~~~! __ !
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 7 typedef __int64 ll; 8 const int maxn = 1e5 + 5; 9 ll d, sum[maxn]; 10 11 int main() 12 { 13 #ifndef ONLINE_JUDGE 14 freopen("in.txt", "r", stdin); 15 #endif // ONLINE_JUDGE 16 int n, m, t; 17 while (scanf("%d", &t) != EOF) { 18 while (t--) { 19 scanf("%d%d", &n, &m); 20 memset(sum, 0, sizeof(sum)); 21 for (int i = 1; i < n; i++) { 22 scanf("%I64d", &d); 23 sum[i+1] = d + sum[i]; 24 } 25 int st, end; 26 for (int i = 1; i <= m; i++) { 27 scanf("%d%d", &st, &end); 28 int beg = (i-1)%n + 1; 29 30 ll ans = 0; 31 if (st < end) { 32 if (beg <= st) // s <= x < y 33 ans = sum[end]-sum[beg]; 34 else if (beg > st && beg < end) // x < s < y 35 ans = 2*(sum[n]-sum[end]) + (sum[end]-sum[beg]) + 2*sum[end]; 36 else if (beg >= end) // x < y < s 37 ans = 2*(sum[n]-sum[beg]) + (sum[beg]-sum[end]) + 2*sum[end]; 38 } 39 else if (st > end) { 40 swap(st, end); 41 if (beg <= st) { // s <= y < x 42 ans = 2*(sum[n]-sum[st]) + sum[st]-sum[beg]; 43 } 44 else if (beg > st && beg < end) { // y < s < x 45 ans = 2*(sum[n]-sum[beg]) + sum[beg]-sum[st]; 46 } 47 else if (beg >= end) { // y < x <= s 48 ans = 2*(sum[n]-sum[beg]) + sum[beg]-sum[st]; 49 } 50 } 51 printf("%I64d\n", ans); 52 } 53 } 54 } 55 return 0; 56 }