poj2965 The Pilots Brothers\' refrigerator

package test;

import java.util.Scanner;

/**问题请参考http://poj.org/problem?id=2965
 * @author rayli

 * @date:2014-7-18 下午2:06:49
 * 题意:在4x4的矩形里,‘+’表示关,‘-’表示开,每一次你能选择[i,j] 如果它是关则变为开,反之亦然.
 * 改变[i,j]的同时,会改变第i行和第j列里面的所有开关。
 * 问最少要多少步,使所有开关都为开状态。
 *java提交没有通过,时间超时了,但看一下,和别人思路差不多,C++及C就能通过
 */
public class BrothersRefrigerator
{
    boolean map[][];
    boolean flag;
    int vistr[];
    int vistc[];
    int ans;
    
    void init()
    {
        map = new boolean [4][4];
        vistr = new int [16];
        vistc = new int [16];
        ans = 0;
    }
    
    void input()
    {
        Scanner cin = new Scanner(System.in);
        char tmp [][] = new char [4][4];

        for(int i=0; i<4; i++)
        {
            tmp[i] = cin.next().toCharArray();
        }
        
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++)
            {
                if(tmp[i][j] == '-')
                    map[i][j] = true;
                else
                    map[i][j] = false;
            }
        
        cin.close();
    }
    
    //当按(r,c)时,同行同列的状态全改变
    void click(int r, int c)
    {
        for(int i=0; i<4; i++)
        {
            map[r][i] = !map[r][i];
            map[i][c] = !map[i][c];
        }
        
        map[r][c] = !map[r][c];
    }
    
    /**
     * 判断此时状态是否为最终全为开的状态
     */
    boolean judge()
    {
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++)
                if(!map[i][j])
                    return false;
        return true;
    }
    
    void DFS(int r, int c, int dp)
    {
        if(dp == ans)
        {
            flag = judge();
            return;
        }
        
        if(flag || r>=4 || dp >= ans)
            return;
        
        click(r, c);
        vistr[dp] = r+1;
        vistc[dp] = c+1;
        
        if(c < 3)
            DFS(r, c+1, dp+1);
        else
            DFS(r+1, 0, dp+1);
        
        click(r, c);
        
        if(c < 3)
            DFS(r, c+1, dp);
        else
            DFS(r+1, 0, dp);
        
        return;
    }
    
    void output()
    {
        for(ans=1; ans<=16; ans++)
        {
//            flag = false;
            
            DFS(0, 0, 0);
            
            if(flag)
                break;
        }
        
        System.out.println(ans);
        
        for(int i=0; i<ans; i++)
        {
            System.out.print(vistr[i]);    
            System.out.println(" " + vistc[i]);
        }
    }
    
    public static void main(String args[])
    {
        BrothersRefrigerator br = new BrothersRefrigerator();
        
        br.init();
        br.input();
        br.output();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值