zoukankan      html  css  js  c++  java
  • poj 2573 Bridge(有A、B、C、D四个人,要在夜里过一座桥……)

    微软面试题题目大意:有A、B、C、D四个人,要在夜里过一座桥。他们通过这座桥分别需要耗时1、2、5、10分钟,只有一支手电,并且同时最多只能两个人一起过桥。

    请问,如何安排,能够在17分钟内这四个人都过桥?

    四个人A(1分钟),B(2分钟),C(5分钟),D(10分钟)

    第一趟:A,B过桥,A(或B)返回;(此趟花费  3(或  4)分钟!)

    第二趟:C,D过桥,B(或A)返回;(此趟花费12(或11)分钟!)

    第三趟:A,B过桥;过桥完毕。       (此趟话费  2分钟!)

    总时间17分钟。

    附:这道题本是ACM世界里的一道编程题(POJ2573),原题是有N个人过桥(场景和上面的一样),他们通过的时间分别是a[1…n],求他们过桥的最短时间。

    这道题有了上面的例子,读者不难想到:

    当人数变多的时候,每次先送最慢的两个人过桥(最快的两个人作为领导者,跑得快嘛,姑且就作为跑腿的)

    左移每次过桥必定有两种过桥办法:

    (假设X,Y为最慢和次慢的过桥者,x,y为最快和次快的过桥者。)

    A:用最快的X陪同最慢和次慢的x,y过桥。

         也就是第一步x,X过桥,x回头(花费x+X分钟);

                 第二步x,Y过桥,x回头(花费Y+x分钟);

        这种方式一次花掉2*x+X+Y分钟。

    B:用最快和次快的x,y陪同最慢和次慢的X,Y过桥。

         也就是第一步x,y过桥,x回头(花费x+y分钟);

                 第二步X,Y过桥,y回头(花费X+y分钟);

        这种方式一次花掉x+2*y+X分钟。

    显然上面的两种方法,当2*x+X+Y<x+2*y+X的时候,选A否则选B过桥。

    如此过桥之后,最后的情况就必然是只剩下两个人或者三个人没有过桥,一个一个的看:

    当剩下两个人的时候(其实就是x,y),两个人一起过桥,花费y分钟。

    当剩下三个人的时候(其实就是x,y,另一个假设为z),此时x,z先过,x回来,x,y再过去,一共花费x+y+z分钟。

    到此处这个题目已经完全可以解出来了,不过在编代码的时候,大家一定要注意,当1,2,3个人的时候,一定要输出过桥的最短时间和过桥的方式,缺一不可,不然会让你WA到想哭。

    好了说这么多,读者自己去思考吧,贴上代码:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 using namespace std;
     4 int n,a[10020];
     5 void init()
     6 {
     7     scanf("%d",&n);
     8     for(int i=1;i<=n;i++)
     9     scanf("%d",&a[i]);
    10     sort(a+1,a+n+1);
    11 }
    12 int slove1(int k)
    13 {
    14     if(k<3) return a[k];
    15     if(k==3) return a[1]+a[2]+a[3];
    16     int minute;
    17     if(a[k-1]+a[1]<2*a[2]) minute=2*a[1]+a[k]+a[k-1];
    18     else  minute=2*a[2]+a[1]+a[k];
    19     minute+=slove1(k-2);
    20     return minute;
    21 }
    22 void slove2(int k)
    23 {
    24     if(k==1) {printf("%d
    ",a[1]);return ;}
    25     if(k==2) {printf("%d %d
    ",a[1],a[2]);return ;}
    26     if(k==3) {printf("%d %d
    %d
    %d %d
    ",a[1],a[3],a[1],a[1],a[2]);return ;}
    27     if(a[k-1]+a[1]<2*a[2]) printf("%d %d
    %d
    %d %d
    %d
    ",a[1],a[k],a[1],a[1],a[k-1],a[1]);
    28     else   printf("%d %d
    %d
    %d %d
    %d
    ",a[1],a[2],a[1],a[k-1],a[k],a[2]);
    29     slove2(k-2);
    30 }
    31 int main()
    32 {
    33     init();
    34     if(n==0) {printf("0
    ");return 0;}
    35     printf("%d
    ",slove1(n));
    36     slove2(n);
    37     return 0;
    38 }
    View Code

     

  • 相关阅读:
    Android 开发 深入理解Handler、Looper、Messagequeue 转载
    Android 开发 Handler的基本使用
    Java 学习 注解
    Android 开发 AlarmManager 定时器
    Android 开发 框架系列 百度语音合成
    Android 开发 框架系列 Google的ORM框架 Room
    Android 开发 VectorDrawable 矢量图 (三)矢量图动画
    Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制
    Android 开发 VectorDrawable 矢量图 (一)了解Android矢量图与获取矢量图
    Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID
  • 原文地址:https://www.cnblogs.com/bokezhilu/p/3580189.html
Copyright © 2011-2022 走看看