Topcoder_161

 【问题描述】
    我从家里(Home)出发,沿着公路骑行。在每一个路口使用投掷硬币的方式来决定方向,正面意味着向左转,背面向右转。如果遇到三个方向(十字路口)可选,那么就投掷硬币两次,两次正面是左转,一正一反是直行,一反一正是右转,两次皆反则再投掷2次来决定。整个过程持续到我能回到家中(Home),下面有一副公路的地图,图中每个选择的路口都用一个字母予以标识。

    题目中会给定一个硬币正反的序列——该序列循环使用,即使用到该序列的最后一个字母后,下一个就是该序列的第一个字母,H代表正面,T代表背面。现在需要计算回到Home的时候我已经投掷了几次硬币。如果永远回不到Home那么就返回-1。
 
  定义:
类  RandomRide
方法  public int flipCount(String flips)

  约束:
1、flips中包含1至50个字母;
2、字母序列仅由'H' 或 'T'组成。

  测试用例:
1、"H"    Returns: 10
2、"HHTTTTTHTHTHHHTT"   Returns: 11
3、"HTH"   Returns: 13
4、"HHHTHHHHHHTTTHHHHHHHHHTTHHT"    Returns: 328
  1. package topcoder.t_1;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. public class RandomRide {
  5.     private Map<String, String> map = null;
  6.     private Map<String, String> repeat = new HashMap<String, String>();
  7.     private int count = 0;
  8.     public int flipCount(String flips) {
  9.         String directStr = flips + flips;
  10.         initMap();
  11.         String start = "#";
  12.         String end = "A";
  13.         String tmp = "";
  14.         while (!"#".equals(end)) {
  15.             tmp = start;
  16.             start = end;
  17.             end = getNextPoint(end, tmp, directStr);
  18.             if ("".equals(end))
  19.                 return -1;
  20.             System.out.println(start + "(" + this.count + ")  ");
  21.         }
  22.         return this.count;
  23.     }
  24.     // 1-left 2-mid 3-right || 1-left 2-right
  25.     private String getNextPoint(String nowPoint, String prePoint, String directStr) {
  26.         String dics = map.get(nowPoint);
  27.         int pos = dics.indexOf(prePoint);
  28.         int direct = getNextDirect(nowPoint, prePoint, directStr);
  29.         if (direct == -1)
  30.             return "";
  31.         return dics.substring(pos + direct, pos + direct + 1);
  32.     }
  33.     private int getNextDirect(String nowPoint, String prePoint, String directStr) {
  34.         int res = 1;
  35.         String dics = map.get(nowPoint);
  36.         boolean isTwo = true;
  37.         if (dics.length() == 7) {
  38.             isTwo = false;
  39.         }
  40.         int len = directStr.length() / 2;
  41.         int pos = this.count % len;
  42.         String ditStr = "TT";
  43.         while (ditStr.equals("TT")) {
  44.             ditStr = directStr.substring(pos, pos + 1);
  45.             if (repeat.containsKey(prePoint + nowPoint + ditStr + pos))
  46.                 return -1;
  47.             else
  48.                 repeat.put(prePoint + nowPoint + ditStr + pos, "");
  49.             if (isTwo) {
  50.                 this.count++;
  51.             } else {
  52.                 ditStr = directStr.substring(pos, pos + 2);
  53.                 pos += 2;
  54.                 pos = pos % len;
  55.                 this.count += 2;
  56.             }
  57.         }
  58.         if (isTwo) {
  59.             if ("H".equals(ditStr))
  60.                 res = 1;
  61.             else
  62.                 res = 2;
  63.         } else {
  64.             if ("HH".equals(ditStr))
  65.                 res = 1;
  66.             else if ("HT".equals(ditStr))
  67.                 res = 2;
  68.             else
  69.                 res = 3;
  70.         }
  71.         System.out.print("[" + ditStr + "]/t");
  72.         return res;
  73.     }
  74.     private void initMap() {
  75.         map = new HashMap<String, String>();
  76.         map.put("A""#BF#B");
  77.         map.put("B""AGCAG");
  78.         map.put("C""BGDBG");
  79.         map.put("D""CHECH");
  80.         map.put("E""DKFDK");
  81.         map.put("F""ELAEL");
  82.         map.put("G""BIHCBIH");
  83.         map.put("H""GJDGJ");
  84.         map.put("I""GMJGM");
  85.         map.put("J""IMKHIMK");
  86.         map.put("K""JNLEJNL");
  87.         map.put("L""KNFKN");
  88.         map.put("M""INJIN");
  89.         map.put("N""MLKML");
  90.     }
  91. }
【算法思想】
    我觉得本题只要解决两个基本问题后就比较简单了,一个是如何建模来方便的处理转向的问题,另一个就是如何判断当前的走法是一种死循环(永远到不了Home)。
   1、第一个问题比较麻烦的地方是,左右是与行驶的方向相关的,为了避免每次都考虑行驶的方向,程序中建立的一个map存储了所有节点的方向信息,例如对于节点B,存储的是"AGCAG",顺序是“后、上、前、下、后、上、前”如果像B一样没有前向节点那么就是“后、上、下、后、上”,Home节点以"#"代表。
   2、第二个问题,程序中维护一个map,如果当前节点的“形式”存在于该map中,那么就认为是重复。这种“形式”为,前一个节点+当前节点+方向+选择的硬币在整个序列中的位置。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值