zoukankan      html  css  js  c++  java
  • java实现纵横火柴棋

    【编程题】
    这是一个纵横火柴棒游戏。如图[1.jpg],在一个3x4的方格中,游戏的双方轮流放置火柴棒。其规则是:

    1. 不能放置在已经放置火柴棒的地方(即只能在空格中放置)。
    
    2. 火柴棒的方向只能是垂直或水平放置。
    
    3. 火柴棒不能与其它格子中的火柴“连通”。所谓连通是指两根火柴棒可以连成一条直线,且中间没有其它不同方向的火柴“阻拦”。
    例如:图[1.jpg]所示的局面下,可以在C2位置竖直放置,但不能水平放置,因为会与A2连通。同样道理,B2,B3,D2此时两种方向都不可以放置。但如果C2竖直放置后,D2就可以水平放置了,因为不再会与A2连通(受到了C2的阻挡)。
    
    4. 游戏双方轮流放置火柴,不可以弃权,也不可以放多根。直到某一方无法继续放置,则该方为负(输的一方)。
    
    游戏开始时可能已经放置了多根火柴。
    
    你的任务是:编写程序,读入初始状态,计算出对自己最有利的放置方法并输出。
    
    如图[1.jpg]的局面表示为:
    

    00-1
    -000
    0100
    即用“0”表示空格位置,用“1”表示竖直放置,用“-”表示水平放置。

    在这里插入图片描述
    【输入、输出格式要求】

    用户先输入整数 n(n<100), 表示接下来输入 n 种初始局面,每种局面占3行(多个局面间没有空行)。

    程序则输出对应的每种初始局面,计算出的最佳走法(行号+列号+放置方式)。

    例如:用户输入:
    2
    0111
    -000
    -000
    1111
    0010

    则程序可以输出:
    00-
    211

    输出结果的含义为:

    对第一个局面,在第0行第0列水平放置

    对第二个局面,在第2行第1列垂直放置

    注意:

    行号、列号都是从0开始计数的。

    对每种局面可能有多个最佳放置方法(解不唯一),只输出一种即可。

    例如,对第一个局面,001 也是正解;最第二个局面,201也是正解。

    
    import java.util.*;
    import java.io.*;
    
    public class Matchstick
    {
    	private char[][] data;
    	
    	public Matchstick(char[][] data)
    	{
    		this.data = data;
    	}
    	
    	// 判断放法的可行性
    	private boolean isGoodStep(int i, int j, char c)
    	{
    		// 本格为空闲吗?
    		if(data[i][j] != '0') return false;
    		
    		data[i][j] = c;
    		try
    		{
    			String s = "";
    			if(c=='1')
    				s = s + data[0][j] + data[1][j] + data[2][j];
    			else
    				s = s + data[i][0] + data[i][1] + data[i][2] + data[i][3];
    			
    			s = s.replaceAll("0","");
    			
    			if(s.indexOf(""+c+c)>=0) return false;
    		}
    		finally
    		{
    			data[i][j] = '0';
    		}
    		
    		return true;
    	}
    	
    	// 一步试放
    	// 在第i行,第j列 试放 c
    	// 必赢,则返回此着法;不能放置或放了必输则返回null
    	private String tryStep(int i, int j, char c)
    	{
    		if(isGoodStep(i,j,c))
    		{
    			data[i][j] = c;
    			try
    			{
    				if(f()==null) return i + "," + j + "," + c;	
    			}
    			finally
    			{
    				data[i][j] = '0';
    			}				
    		}
    		return null;
    	}
    	
    	// 评价data局面
    	// 如果必输,返回null
    	// 如果必赢,返回必赢的着法之一
    	public String f()
    	{
    		for(int i=0; i<3; i++)
    		for(int j=0; j<4; j++)
    		{
    			String rt = null; 
    			
    			rt = tryStep(i,j,'1');
    			if(rt!=null) return rt;
    			
    			rt = tryStep(i,j,'-');
    			if(rt!=null) return rt;
    		}
    		return null;
    	}
    	
    	private static char[][][] readData() throws IOException
    	{
    		Scanner scan = new Scanner(System.in);
    		int n = Integer.parseInt(scan.nextLine());
    		char[][][] rt = new char[n][3][4];
    		
    		for(int k=0; k<n; k++)
    		{
    			for(int i=0; i<3; i++)
    			{
    				String s = scan.nextLine().trim();
    				for(int j=0; j<4; j++)
    					rt[k][i][j] = s.charAt(j);
    			}
    		}
    		
    		return rt;
    	}
    	
    	static private void writeResult(String[] ss)
    	{
    		for(int i=0; i<ss.length; i++)
    		{
    			if(ss[i]==null)
    				System.out.println("000");  // 权宜之计,应该选择某个可行的走法
    			else
    				System.out.println(ss[i].replaceAll(",",""));
    		}
    	}
    	
    	public static void main(String[] args) throws Exception
    	{
    		// 局面
    		//char[][] a = {{'0','1','1','0'},{'-','0','0','0'},{'-','0','0','0'}};
    		//char[][] a = {{'-','0','0','0'},{'0','0','0','0'},{'0','0','0','0'}};
    		
    		char[][][] a = readData();
    		String[] b = new String[a.length]; 
    		
    		for(int i=0; i<a.length; i++)
    		{
    			b[i] = new Matchstick(a[i]).f();
    		}
    		
    		writeResult(b);
    	}
    }
    
  • 相关阅读:
    OLAP ODS项目的总结 平台选型,架构确定
    ORACLE ORA12520
    ORACLE管道函数
    ORACLE RAC JDBC 配置
    ORACLE RAC OCFS连接产生的错误
    ORACLE 启动和关闭详解
    OLAP ODS项目的总结 起步阶段
    ORACLE RAC 配置更改IP
    ORACLE RAC OCR cann't Access
    ORACLE RAC Debug 之路 CRS0184错误与CRS初始化
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13076908.html
Copyright © 2011-2022 走看看