zoukankan      html  css  js  c++  java
  • 【USACO 1.4.2】时钟

    【题目描述】

    考虑将如此安排在一个 3 x 3 行列中的九个时钟:

     |-------|    |-------|    |-------|
     |       |    |       |    |   |   |
     |---O   |    |---O   |    |   O   |
     |       |    |       |    |       |
     |-------|    |-------|    |-------|
         A            B            C
    
     |-------|    |-------|    |-------|
     |       |    |       |    |       |
     |   O   |    |   O   |    |   O   |
     |   |   |    |   |   |    |   |   |
     |-------|    |-------|    |-------|
         D            E            F
    
     |-------|    |-------|    |-------|
     |       |    |       |    |       |
     |   O   |    |   O---|    |   O   |
     |   |   |    |       |    |   |   |
     |-------|    |-------|    |-------|
         G            H            I
    

    目标要找一个最小的移动顺序将所有的指针指向12点。下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。

    移动方法  受影响的时钟 
    1        ABDE
    2        ABC
    3        BCEF
    4        ADG
    5        BDEFH
    6        CFI
    7        DEGH
    8        GHI
    9        EFHI
    
    

    Example

    9 9 12          9 12 12       9 12 12        12 12 12         12 12 12
    6 6 6   5 ->    9  9  9   8-> 9  9  9   4 -> 12  9  9   9 ->  12 12 12
    6 3 6           6  6  6       9  9  9        12  9  9         12 12 12
    
    [但这可能不是正确的方法,请看下面]

    【格式】

    INPUT FORMAT:

    (file clocks.in)

    第1-3行: 三个空格分开的数字,每个数字表示一个时钟的初始时间,3,6,9,12。数字的含意和上面第一个例子一样。

    OUTPUT FORMAT:

    (file clocks.out)

    单独的一行包括一个用空格分开的将所有指针指向12:00的最短移动顺序的列表。

    如果有多种方案,输出那种使其连接起来数字最小的方案。(举例来说5 2 4 6 < 9 3 1 1)。

    【分析】

    好吧,我偷懒了......用了9重循环的方法。

    九重循环的方法大家都会,不解释了,实际上,网上流传有一种很好的方法可以在很短的时间内解决。

    如下:

    首先可以求出一个数组cnt[i][j],表示第i个钟转到12点需要使用方法j共cnt[i][j]次。

    eg.只将第一个钟转90度,那么需要使用方法一3次、方法二3次、方法三3次、……、方法九0次(即{3,3,3,3,3,2,3,2,0})

    于是,只需要知道每个钟要转几次,再mod 4(同一种方法使用4次,等于没转),就能得出答案。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <algorithm>
     6 const int maxn=10000;
     7 using namespace std;
     8 struct Clock
     9 {
    10        int clock[15];
    11 }data,now;
    12 int mz[15],ans[maxn*2],rem[maxn*2];
    13 int change[15][15]=
    14 {
    15     {0,3,3,0,3,3,0,0,0,0},
    16     {0,3,3,3,0,0,0,0,0,0},
    17     {0,0,3,3,0,3,3,0,0,0},
    18     {0,3,0,0,3,0,0,3,0,0},
    19     {0,0,3,0,3,3,3,0,3,0},
    20     {0,0,0,3,0,0,3,0,0,3},
    21     {0,0,0,0,3,3,0,3,3,0},
    22     {0,0,0,0,0,0,0,3,3,3},
    23     {0,0,0,0,0,3,3,0,3,3},
    24 };
    25 inline int MOD(int num) {return num%12==0?12:num%12;}
    26 
    27 int main()
    28 {
    29     int i,j,k;
    30     //文件操作 
    31     freopen("clocks.in","r",stdin);
    32     freopen("clocks.out","w",stdout);
    33     for (i=1;i<=9;i++) scanf("%d",&data.clock[i]);
    34 
    35     ans[0]=0x7fffffff;
    36     //枚舉 
    37     for (mz[0]=0;mz[0]<4;mz[0]++)
    38     for (mz[1]=0;mz[1]<4;mz[1]++)
    39     for (mz[2]=0;mz[2]<4;mz[2]++)
    40     for (mz[3]=0;mz[3]<4;mz[3]++)
    41     for (mz[4]=0;mz[4]<4;mz[4]++)
    42     for (mz[5]=0;mz[5]<4;mz[5]++)
    43     for (mz[6]=0;mz[6]<4;mz[6]++)
    44     for (mz[7]=0;mz[7]<4;mz[7]++)
    45     for (mz[8]=0;mz[8]<4;mz[8]++)
    46     {
    47         int lj=0,point=0,flag=1;
    48         for (i=0;i<=8;i++) lj+=mz[i];  
    49         if (lj>ans[0]) continue;//跳过
    50         
    51         now=data;  
    52         //逐位提取
    53         for (i=0;i<=8;i++)
    54         for (j=1;j<=mz[i];j++)
    55         {
    56             for (k=1;k<=9;k++)  
    57             now.clock[k]=MOD(now.clock[k]+change[i][k]);                              
    58         }
    59         
    60         //判断是否满足条件 
    61         for (i=1;i<=9;i++) if (now.clock[i]!=12) {flag=0;break;}
    62         if (flag==0) continue;
    63         
    64         //构造解 
    65         for (i=0;i<=8;i++) 
    66         for (j=1;j<=mz[i];j++) rem[++point]=i; 
    67         
    68         if (lj==ans[0])
    69         {
    70             for (i=1;i<=ans[0];i++)
    71             if (rem[i]>ans[i]) {flag=0;break;}
    72         }
    73         if (flag==0) continue;
    74         ans[0]=lj;
    75         for (i=1;i<=ans[0];i++) ans[i]=rem[i];
    76         
    77     }
    78     for (i=1;i<=ans[0];i++) printf("%d ",ans[i]+1);
    79     return 0;
    80 }
  • 相关阅读:
    HTML5 中的Nav元素详解
    Gevent中信号量的使用
    MemCache缓存multiget hole详解
    MemCache中的内存管理详解
    Php中的强制转换详解
    Python中类的特殊方法详解
    MemCache的LRU删除机制详解
    AngularJS事件绑定的使用详解
    Php数据类型之整型详解
    HTML基础知识
  • 原文地址:https://www.cnblogs.com/hoskey/p/3784757.html
Copyright © 2011-2022 走看看