zoukankan      html  css  js  c++  java
  • 【Topcoder】SRM157 DIV2总结

    250分题:简单的二分,就是平常玩的猜数字游戏

    代码:GitHub

    500分题:给出一个员工一天的打卡时间段,要求求出员工这一天的工资。其中正常上班时间是6:00:00到18:00:00,薪水是wage,其他时间薪水是1.5*wage。

    我的思路比较直接,将时间分成三个时间段分别计算:00:00~06:00,06:00~18:00,18:00~23:59:59。伪码如下:

     1 if(arrival time < 06:00:00)
     2        money += 1.5*wage*(min(06:00:00,departure time)-arrival time);
     3        if(departure time > 06:00:00)
     4          arrival time = 06:00:00;
     5 
     6 if(arrival time >= 06:00:00 && arrival time <18:00:00)
     7         money += wage*(min(departure time,18:00:00) - 06:00:00);
     8         if(departure time > 18:00:00)
     9             arrival time = 18:00:00;
    10 
    11 if(arrival time >= 18:00:00)
    12         money += 1.5*wage*(departure time - arrival time);

    具体实现的时候,我直接用了java的date类,算时间差的时候就很麻烦,其实只要把所有时间都转换成秒,然后计算这个人每秒赚多少钱,这样无论是比较时间的大小还是计算两个时间点的差值都非常容易。所以积累一点,以后遇到要比较时间大小和差值的,尽量转换成秒来计算,会省去很多麻烦。不过今天做了半天,积累了一些关于java的date类的知识,积累如下:

    1.讲形如“HH:mm:ss”的字符串转换为Date型:

    SimpleDateFormat fommater = new SimpleDateFormat("HH:mm:ss");
    Date arriDate = fommater.parse(arrival);

    上述的parse函数可能会抛出ParseException异常,需要处理。

    2.判断时间t1是否在时间t2的前面或者后面:

    t1.before(t2);
    t1.after(t2);

    3.求时刻t1和t2的差值(单位是毫秒)

    long bewteen = t1.getTime() - t2.getTime();

    最后完整的代码:GitHub

    这道题官方还给了一个很简便的解法:把arrival time和departure time都变成秒为单位后,直接从arrival time一秒一秒的遍历到departure time,如果当前的一秒在正常上班范围内,增加计数器t1;如果在加班的范围内,增加计数器t2,最后得到的钱就是wage*t1+1.5*wage*t2(wage是每秒赚的钱)。这个方法比上面分三段判断实现起来要简单很多。

    1000分题:给出两个沙漏,一个可以用来衡量出时间glass1,一个可以用来衡量出glass2,要求求出前十个最小的能够衡量出的时间。

    第一眼看没思路,看了解答才发现要用递归+备忘录的方法:递归函数helper定义为void helper(int sand1,int sand2,int time)表示在时刻time,两个沙漏分别能够衡量出时间sand1和sand2,此时有两种可能

    1.sand1或者sand2至少一个漏空了,那么我们有四种选择:

        (1)把sand1倒过来,sand2不动,递归调用helper(glass1-sand1,sand2,time);

        (2)把sand2倒过来,sand1不动,递归调用helper(sand1,glass2-sand2,time);

        (3)把sand1和sand2全部倒过来,递归调用helper(glass1-sand1,glass2-sand2,time);

        (4)sand1和sand2都不动,等待没空的那个漏空,此时需要看两个沙漏哪个还没漏完,假设1还没漏完,就递归调用helper(0,0,time+sand1);

    2.sand1和sand2都没有漏空,那么我们必须要等待他们中有较少的沙的沙漏漏完才能有动作,此时递归调用helper(sand1-min(sand1,sand2),sand2-min(sand1,sand2),time+min(sand1,sand2)。

    如果单纯的递归会超时,因为对于同一组(sand1,sand2,time),在递归的过程中,我们可能会多次重复调用,所以要用备忘录visited[][][]记录我们掉用过哪些sand1,sand2,time,避免重复的调用。

    最后代码:GitHub

    官方完整题解

  • 相关阅读:
    【luogu P1307 数字反转】 题解
    【luogu P1111 公路修建】 题解
    字符串与正则运算
    Java 正则表达式的总结和一些小例子
    js -history.back(-1)和history.go(-1) 区别
    js
    html _ 提取html片段内的纯文本
    vue-x action 的相互调用
    java通过过滤器 设置跨域允许
    git-搭建企业git服务器
  • 原文地址:https://www.cnblogs.com/sunshineatnoon/p/3935154.html
Copyright © 2011-2022 走看看