UVA 10037 Bridge

题目

过桥

分析


  1. 贪心;
  2. 有一座桥,一次仅能通过两人,通过的条件是持有手电筒,所以手电筒需要有人带回。输出最短的通过时间以及通过过程。
  3. 过桥有两个最优策略。

策略一
最快的小伙砸(a)把左岸最慢的小伙砸(z)带到右岸再回来,再把次慢的小伙砸(y)带过去再回来,其时间为z+a+y+a

策略二
最快的小伙砸和次快的小伙砸(b)到对岸,最快的小伙砸把手电筒带回来,最慢和次慢的到对岸,次快的小伙砸把手电筒带回来,其时间为b+a+y+b

其取舍只需比较z+a+y+ab+a+y+b孰大孰小即可。

思路

  1. 排序输入的时间;
  2. 分类讨论n = 1, 2, 3n > 3 的情况,因为n不足4时不需要四次过桥,也就是不符合上述讨论的策略,但不足4的情况也易解。
  3. 对于n > 3的情况只需比较一下策略一和策略二的时长,便可得出要采用哪一策略。
  4. 因为过程要在时长后输出,所以需要滚两次,第一次得到时长,第二次输出过程。

代码

#include <cstdio>
#include <algorithm>
using namespace std;

int main()
{
    int c, n, t[1005], s, i;
    scanf("%d", &c);
    while (c--) {
        scanf("%d", &n);
        for (i = 0; i < n; i++)
            scanf("%d", &t[i]);
        sort(t, t+n);
        s = 0;
        while (n) {
            if (n == 1) { s += t[0]; break; }
            if (n == 2) { s += t[1]; break; }
            if (n == 3) { s += t[1]+t[0]+t[2]; break; }
            if (t[n-1] + t[0] + t[n-2] + t[0] < t[1] + t[0] + t[n-1] + t[1])
                s += t[n-1] + t[0] + t[n-2] + t[0];
            else
                s += t[1] + t[0] + t[n-1] + t[1];
            n -= 2;
        }
        printf("%d\n", s);
        n = i;
        while (n) {
            if (n == 1) { printf("%d\n", t[0]); break; }
            if (n == 2) { printf("%d %d\n", t[0], t[1]); break; }
            if (n == 3) { printf("%d %d\n%d\n%d %d\n", t[0], t[2], t[0], t[0], t[1]); break; }
            if (t[n-1] + t[0] + t[n-2] + t[0] < t[1] + t[0] + t[n-1] + t[1])
                printf("%d %d\n%d\n%d %d\n%d\n",t[0], t[n-1], t[0], t[0], t[n-2], t[0]);
            else
                printf("%d %d\n%d\n%d %d\n%d\n", t[0], t[1], t[0], t[n-2], t[n-1], t[1]);
            n -= 2;
        }
        if (c) printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值