zoukankan      html  css  js  c++  java
  • The Clocks

    【原题链接】

    【题意说明】

    一组9面钟的初始时间点数,时间只能为3、6、9、12这四种整点数,再给出9种拨动钟表的方案,每次每面钟最多能顺时针拨动90度,即由3->6,6->9,9->12,12->3。问最少使用几种方案,就可使所有的钟表都拨到12点!若使用拨动方案数相同,则输出字典序最小的方案。

    9面钟编号:

    A B C
      D E F
      G H I

    移动方案:

    1  ABDE
      2  ABC
      3  BCEF
      4  ADG
      5  BDEFH
      6  CFI
      7  DEGH
      8  GHI
      9  EFHI

    【问题分析】

    首先我思考的是搜索,求最优,如何保存状态呢?状态压缩,可以看出:每种方案最多使用0~3次(因为使用4次就相当于没有使用),所以最多的状态为4^9=26144,经过编码,完全可以保存下来,而且搜索的时间复杂度应该不算太高!当然如果使用dfs,完全无视空间的状态存储(基本不会栈溢出了)!只需要考虑一下适当的剪枝,进行优化即可!

    这里再来说说非搜索的思路:

    (1)所有的钟面只有4种状态(3,6,9,12),对就可转化为(1,2,3,0)

    (2)所有的方案只能拨动某些钟面到下一个状态,如方案1可拨动A、B、D、E,其它的不能拨动,我们可以把它扩展记为1 1 0 1 1 0 0 0 0,表示对9面钟的控制状态。这样所有的方案转化为:

    1 1 0 1 1 0 0 0 0
      1 1 1 0 0 0 0 0 0
      0 1 1 0 1 1 0 0 0
      1 0 0 1 0 0 1 0 0
      0 1 0 1 1 1 0 1 0
      0 0 1 0 0 1 0 0 1
      0 0 0 1 1 0 1 1 0
      0 0 0 0 0 0 1 1 1
      0 0 0 0 1 1 0 1 1

    这样可以看出这个表(记录A[i][j])中的每列都是控制一面钟,若假定每种方案的使用次数为b[i],每面钟的初始状态为c[i],这样就可以计算出每面钟最少需要拨动几次就能达到目标状态,修改c[i]的值为最少拨动的次数。这样我们就可以建立以下的方程:

    sum(A[i][j]*b[i])%4=c[j](其中b[i]表示第i种方案使用的次数,且0≤b[i]≤3)

    写成一般方程组形式为:Ab=c -->b=A-1c,(其中:A为方程的系数矩阵,A-1为矩阵的逆)

    这样我只要求出矩阵A的逆,即可计算出b[i]的值。由数论的知识可知通过初等行变换,可以把A|E-->E|A-1,注意在求逆的过程中,要加遇负转正,且要模4的处理,最终计算得A-1为:

    3 3 3 3 3 2 3 2 0
      2 3 2 3 2 3 1 0 1
      3 3 3 2 3 3 0 2 3
      2 3 1 3 2 0 2 3 1
      2 3 2 3 1 3 2 3 2
      1 3 2 0 2 3 1 3 2
      3 2 0 3 3 2 3 3 3
      1 0 1 3 2 3 2 3 2
      0 2 3 2 3 3 3 3 3

    至此,我们就可以通过二重循环以求得每个b[i]的值,即:

    b[i]=sum(A-1[i][j]*c[j])%4

    最后按要求输出这些b[i]的值即可。

  • 相关阅读:
    [BS] 小知识点总结-02
    [BS] 小知识点总结-03
    [BS] 小知识点总结-01
    [BS-12] JSON的基础知识--百科
    [BS-11] 关于RGB/ARGB颜色相关知识
    Mac自定义隐藏或显示文件的快捷键
    iOS开发环境C语言基础
    Objective -C Memory Management 内存管理 第一部分
    Objective-C Foundation 框架 Example :Looking for Files 查找文件
    Objective
  • 原文地址:https://www.cnblogs.com/ahmasoi/p/2762399.html
Copyright © 2011-2022 走看看