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 }
  • 相关阅读:
    vim复制
    嵌入式Linux学习(二)
    (Java实现) 洛谷 P1042 乒乓球
    (Java实现) 洛谷 P1042 乒乓球
    (Java实现) 洛谷 P1071 潜伏者
    (Java实现) 洛谷 P1071 潜伏者
    (Java实现) 洛谷 P1025 数的划分
    (Java实现)洛谷 P1093 奖学金
    (Java实现)洛谷 P1093 奖学金
    Java实现 洛谷 P1064 金明的预算方案
  • 原文地址:https://www.cnblogs.com/hoskey/p/3784757.html
Copyright © 2011-2022 走看看