poj日记(1222)

import java.util.Scanner;  
  
public class Main{  
  
    /*解题思路 
     *  
     * 1.时钟的状态只有四种(分别对应0.1.2.3),那么顺时针旋转90° 
     * 就是clock_time = (clock_time+1)%4,九个时钟就用一个 
     * 数组表示它们的状态。 
     * 2.同时每一种操作都有周期性限制,也即最多需要几次操作,多于这个 
     * 次数产生循环。本题中,操作的最多次数为3,如果操作四次,则和没有 
     * 操作是一样的..故用一个数组表示九个操作每个操作需要进行的次数。 
     * 3.对移动方法进行枚举,枚举方法123,共64种情况,则A的状态只 
     * 能通过操作4来改变,所以要A达到十二点,那么操作4的次数是一定的了。 
     * 同理,改变B只能操作5,改变C只能操作6。那么操作123456的次数确定。 
     * 4.这时候,同理改编D只能操作7,改编F只能操作9,所以12345679确定。 
     * 5.这时候还剩EGHI还没确定,操作8还没确定。由于操作8只能同时改编GHI, 
     * 不改变E,那么看看E是否已经到达十二点,看看GHI是否相同。 
     *  
     */  
    static private int[] clock_time;    //时钟初始状态  
    static private int[] enumeration;   //用于枚举123操作,初始000  
    static private int min_time = 28;       //记录当前最少序列  
    static private int[] min_seq;  
    //9种操作  
    static private int [][] op = new int[][]{  
        //A B C D E F G H I  
        {1,1,0,1,1,0,0,0,0},    //op1:ABDE  
        {1,1,1,0,0,0,0,0,0},    //op2:ABC  
        {0,1,1,0,1,1,0,0,0},    //op3:BCEF  
        {1,0,0,1,0,0,1,0,0},    //op4:ADG  
        {0,1,0,1,1,1,0,1,0},    //op5:BDEFH  
        {0,0,1,0,0,1,0,0,1},    //op6:CFI  
        {0,0,0,1,1,0,1,1,0},    //op7:DEGH  
        {0,0,0,0,0,0,1,1,1},    //op8:GHI  
        {0,0,0,0,1,1,0,1,1}     //op9:EFHI  
    };  
      
    static private void input(){  
        Scanner sc = new Scanner(System.in);  
        clock_time = new int[9];  
        for(int i = 0; i < 9; i++){  
            clock_time[i] = sc.nextInt();  
        }  
    }  
    //枚举操作123的不同次数,每次枚举都+1  
    static private void enumerate(){  
        enumeration[0]++;  
        if(enumeration[0] == 4){  
            enumeration[1]++;  
            enumeration[0] = 0;  
        }  
        if(enumeration[1] == 4){  
            enumeration[2]++;  
            enumeration[1] = 0;  
        }  
    }  
      
    //由一种枚举状态,确定此状态能否达成要求,若达到要求,返回总的操作次数,达不到要求,返回28次  
    //1.确定123的操作次数(已经得到)  
    //2.施加123操作给所有时钟,得到ABC的状态,从而确定456的操作次数  
    //3.施加456操作给所有时钟,得到DF的状态,从而确定79的操作次数  
    //4.施加79操作给所有时钟,得到EGHI的状态  
    //5.判断GHI是否相同,E是否达到12点,若其一条件不满足,则返回28次  
    //6.如果满足,确定8操作的次数。输出所有操作,根据次数确定该操作重复输出的次数  
    public static void guess(int []enumeration){  
//      System.out.println("本次枚举:");  
//      for(int i = 0; i < 3; i++){  
//          System.out.print(enumeration[i] + " ");  
//      }  
//      System.out.println();  
              
              
        //临时记录状态的时钟  
        int [] t = new int[9];  
        for(int i = 0; i<9;i++){  
            t[i] = clock_time[i];  
        }  
        //每种操作执行的次数  
        int [] opn = new int[9];  
        opn[0] = enumeration[0];  
        opn[1] = enumeration[1];  
        opn[2] = enumeration[2];  
        //施加123操作给所有时钟  
        for(int i = 0; i < 3; i++){  
            for(int j = 0; j < 9; j++){  
                t[j] = (t[j] + opn[i] * op[i][j])%4;  
            }  
        }  
          
//      System.out.println("施加操作123后:");  
//      for(int j = 0; j < 9; j++){  
//          System.out.print(t[j] + " ");  
//      }  
//      System.out.println();  
          
        //通过ABC的状态,得到456的操作次数  
        opn[3] = (4 - t[0]) % 4;  
        opn[4] = (4 - t[1]) % 4;  
        opn[5] = (4 - t[2]) % 4;  
          
        //施加456操作给所有时钟  
        for(int i = 3; i < 6; i++){  
            for(int j = 0; j < 9; j++){  
                t[j] = (t[j] + opn[i] * op[i][j])%4;  
            }  
        }  
          
//      System.out.println("施加操作456后:");  
//      for(int j = 0; j < 9; j++){  
//          System.out.print(t[j] + " ");  
//      }  
//      System.out.println();  
          
        //通过DF,确定79的操作次数  
        opn[6] = (4 - t[3]) % 4;  
        opn[8] = (4 - t[5]) % 4;  
          
        //施加79操作给所有时钟  
        for(int i = 6; i <= 8; i++){  
            if(i == 7)  
                continue;  
            for(int j = 0; j < 9; j++){  
                t[j] = (t[j] + opn[i] * op[i][j])%4;  
            }  
        }  
                  
//      System.out.println("施加操作79后:");  
//      for(int j = 0; j < 9; j++){  
//          System.out.print(t[j] + " ");  
//      }  
//      System.out.println();  
          
        //判断  
        if(t[4] != 0 || t[6] != t[7] || t[7] != t[8])  
        {  
//          System.out.println("本次不满足条件");  
            return;  
        }  
        //计算操作8  
        opn[7] = (4 - t[6]) % 4;  
//      System.out.println("本次操作序列:");  
        int sum = 0;  
        for(int i = 0; i < 9; i++){  
            sum += opn[i];  
        }  
        if(sum < min_time){  
            min_seq = opn;  
        }  
        else  
            return;  
    }  
      
    public static void main(String[] args) {  
        input();  
        enumeration = new int[3];   //自动初始化000  
        for(int i = 0; i < 64;i++){  
            guess(enumeration);  
            enumerate();  
        }  
        for(int i = 0; i < 9; i++){  
            for(int j = 0; j < min_seq[i]; j++){  
                System.out.print(i + 1 + " ");  
            }  
        }  
    }  
  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值