BestCoder27 1002.Taking Bus(hdu 5163) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5163

题目意思:有 n 个车站,给出相邻两个车站的距离,即车站 i 和车站 i+1 的距离为 di (1i <n)。然后是 m 个人从他的出发点到他想去的终点(都是车站),约定轮到处理第 i 个人的时候,车站的出发点满足:((i-1) mod n) + 1 ,假设车每走一个单位的距离花费一个单位的时间,车开始的时候是从左到右开的。如果车走到最右的车站即车站 n 会调头,此时方向为从右到左开;如果车走到最左即车站 1,方向转为从左到右开。求出每个人从他出发点到终点需要的最少时间是多少。注意,这个人的出发点不一定和车的出发点相同,此时他要候车,候车时间也计算在内。

      赛中过于浮躁,来不及写完......

  赛后各种 wa,各种wa.......

      思路是对的,就是分六种情况,通过画图,写出公式

    1. sx<y,      2. x<s<y,     3. x<ys,      4. sy<x,      5. y<s<x,       6. y<xs

     

      通过公式的化简,发现有些情况是可以合并的。当 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 路 。呜呜呜呜呜呜~~~~! __ !

   

 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 }
View Code

 

 

 

    

转载于:https://www.cnblogs.com/windysai/p/4248055.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值