棋盘覆盖过程演示

先来几张效果图:



问题描述: 有一个的棋盘,和一个坏点,问能否用若干个由三个小方格组成的"L"形的物体覆盖完整个棋盘(不包括坏点)

解决思路:  这是一个分治的典型问题,唔~刚好是作业~.因为棋盘可以均分成四个部分,左上角,左下角,右上角和右下角,坏点必定在其中一个部分,可以发现,分割后的每一个正方形仍然可以分割,直至其大小为 2 X 2.在分割过程中,四个正方形交界处有四个小方格,假设坏点在正方形 A 中则把四个小方格中属于 正方形B和C和D中的交界处小方格也当作坏点,这样,分割到最后 2 X 2 的时候必然有一个坏点,剩余的三个小方格刚好组成一个 "L" 形.


下面是代码:


首先是主函数,创建一个窗体负责接收输入信息,运行结果是上面左图.

package code;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class asdfghjkl implements ActionListener
{
	JFrame jf = new JFrame("棋盘覆盖") ;
	JButton re = new JButton("重置") ;
	JButton next = new JButton("下一步") ;
	JButton ok = new JButton("演示") ;
	JButton cl = new JButton("关闭") ;
	JLabel posx = new JLabel("横坐标") ;
	JLabel posy = new JLabel("纵坐标") ;
	JLabel hesize = new JLabel("棋盘大小(1-5)") ;
	JTextField tx = new JTextField() ;
	JTextField ty = new JTextField() ;
	JTextField sz = new JTextField() ;
	
	public asdfghjkl() {
		// TODO Auto-generated constructor stub
		jf.setSize(300, 200);
		jf.setResizable(false) ;
		jf.setLayout(new GridLayout(4, 2));
		jf.add(hesize) ;
		jf.add(sz) ;
		jf.add(posx) ;
		jf.add(tx) ;
		jf.add(posy) ;
		jf.add(ty) ;
		ok.addActionListener(this);
		re.addActionListener(this);
		jf.add(ok) ;
		jf.add(re) ;
		jf.setVisible(true);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Init() ;
	}
	private void Init() {
		// TODO Auto-generated method stub
		tx.setText(null);
		ty.setText(null);
		sz.setText(null);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getSource().equals(ok)) {
			if (sz.getText().equals("") || tx.getText().equals("") || ty.getText().equals("")) {
				JOptionPane.showMessageDialog(jf,"error" ,"error input",JOptionPane.ERROR_MESSAGE);
			}
			int chesssize = 1 , k = Integer.valueOf(sz.getText()) ;
			int x = Integer.valueOf(tx.getText()) , y = Integer.valueOf(ty.getText()) ;
			if (k < 1 || k > 5) {
				JOptionPane.showMessageDialog(jf,"error" ,"error input",JOptionPane.ERROR_MESSAGE);
			}// <span style="font-family:KaiTi_GB2312;">保证输入信息都是有效的</span>
			for (int i = 1 ; i <= k ; ++ i) chesssize *= 2 ;
			REC sb = new REC(1,1,chesssize) ;
			REC sa = new REC(x,y,0) ;
			if (!sb.baohan(sa)) {
				JOptionPane.showMessageDialog(jf,"error" ,"error input",JOptionPane.ERROR_MESSAGE);
			}
			new Mydialog(jf,chesssize,sa) ;
		}
		else if (e.getSource().equals(re)) {
			Init();
		}
		
	}
}

public class Work {
	public static void main(String[] agrs) {
		String lookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; 
		try {
			UIManager.setLookAndFeel(lookAndFeel) ;
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
				| UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		new asdfghjkl();
		TimeCount x = new TimeCount() ;
		x.start();
	}
}


下面是主函数中用到的几个自定义类

  • REC 表示一个起点是(x,y),长度是 len 的正方形.
  • MyDialog 表示弹出一个对话框,owner 是主函数中的jframe
  • TimeCount 表示一个每个100 ms 执行一次justshownext的线程

REC:

package code;

class REC
{
	public int x , y , len ;
	public REC() {
		// TODO Auto-generated constructor stub
		this.x = this.y = this.len = 0 ;
	}
	public REC(REC rt) {
		this.x = rt.x ;
		this.y = rt.y ;
		this.len = rt.len ;
	}
	public REC(int x,int y,int len) {
		this.x = x ;
		this.y = y ;
		this.len = len ;
	}
	public boolean baohan(REC rec) {
		if (rec.x >= this.x && rec.x <= (this.x+this.len-1) && rec.y >= this.y && rec.y <= (this.y+this.len-1)) return true ;
		return false ;
	}
	public boolean baohan(REC rec[],int cnt) {
		for (int i = 0 ; i < cnt ; ++ i) {
			if (this.baohan(rec[i])) return true ;
		}
		return false;
	}
} 


TimeCount

package code;

class TimeCount extends Thread
{
	long timesec ;
	public TimeCount() {
		timesec = 0;
	}
	public void run() {
		while (true) {
			try {
				if (Mydialog.ok) Mydialog.justshownext() ;
				Thread.sleep(100);
			}
			catch (Exception e) {}
		}
	}
}







MyDialog


package code;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

class Mydialog implements ActionListener
{
	JButton up = new JButton("上一步") ;
	JButton ne = new JButton("下一步") ;
	JButton cl = new JButton("关闭") ;
	JButton be = new JButton("开始") ;
	JButton sp = new JButton("暂停") ;
	JFrame jf = new JFrame() ;
	JDialog diacp ;
	static int vis[][] = new int[33][33] ;
	static JLabel[][] chess ;
	static int chesssize ;
	int cnt = 0;
	static int k = 0;
	static int nowk = 0;
	int xxx = 1 ;
	public static boolean ok = false ;
	REC pos ;
	REC[] rec ;
	
	@SuppressWarnings("static-access")
	public Mydialog(JFrame jf,int chesssize,REC pos) {
		this.chesssize = chesssize ;
		this.jf = jf ;
		this.pos = pos ;
		nowk = k = cnt = 0 ;
		rec = new REC[chesssize*chesssize+1] ;
		rec[cnt++] = new REC(pos) ;
		diacp = new JDialog(jf, "演示", true) ;
		Init() ;
		
	}
	
	private void Init() {
		// TODO Auto-generated method stub
		Container cp = diacp.getContentPane() ;
		JPanel pa1 = new JPanel(new FlowLayout());
		ne.addActionListener(this);
		up.addActionListener(this);
		cl.addActionListener(this);
		be.addActionListener(this);
		sp.addActionListener(this);
		pa1.add(be) ;
		pa1.add(sp) ;
		pa1.add(ne) ;
		pa1.add(up) ;
		pa1.add(cl) ;
		JPanel pa2 = new JPanel(new GridLayout(chesssize,chesssize)) ;
		chess = new JLabel[chesssize+1][chesssize+1] ;
		for (int i = 1 ; i <= chesssize ; ++ i) {
			for (int j = 1 ; j <= chesssize ; ++ j) {
				chess[i][j] = new JLabel() ;
				vis[i][j] = -1;
				chess[i][j].setOpaque(true);
				chess[i][j].setBackground(Color.white);
				pa2.add(chess[i][j]) ;
			}
		}
		chess[pos.x][pos.y].setBackground(Color.black);
		vis[pos.x][pos.y] = -2 ;
		cp.add(pa1, BorderLayout.NORTH);
		cp.add(pa2, BorderLayout.CENTER);
		diacp.setSize(500, 500);
		diacp.setVisible(true);
		
	}
	
	void presolve(REC rt) {
		// TODO Auto-generated method stub
		if (rt.len == 2) {
			for (int i = rt.x ; i < rt.x + rt.len ; ++ i) {
				for (int j = rt.y ; j < rt.y + rt.len ; ++ j) {
					if (vis[i][j] == -1) {
						vis[i][j] = k ;
					}
				}
			}
			k ++ ;
		}
		else {
			REC[] A = new REC[5] ;
			REC[] B = new REC[5] ;
			A[1] = new REC(rt.x,rt.y,rt.len/2) ;// left and up
			A[2] = new REC(rt.x,rt.y+rt.len/2,rt.len/2) ; //right and up
			A[3] = new REC(rt.x+rt.len/2,rt.y,rt.len/2) ; // left and down
			A[4] = new REC(rt.x+rt.len/2,rt.y+rt.len/2,rt.len/2) ; // right and down
			B[1] = new REC(A[4].x-1,A[4].y-1,0) ;
			B[3] = new REC(A[4].x,A[4].y-1,0) ;
			B[2] = new REC(A[4].x-1,A[4].y,0) ;
			B[4] = new REC(A[4].x,A[4].y,0) ;
			for (int i = 1 ; i <= 4 ; ++ i) {
				if (A[i].baohan(rec, cnt)) {
					for (int j = 1 ; j <= 4 ; ++ j) {
						if (i != j) {
							rec[cnt++] = new REC(B[j]) ;
							vis[B[j].x][B[j].y] = -2 ;
						}
					}
					break ;
				}
			}
			for (int i = 1 ; i <= 4 ; ++ i) {
				presolve(A[i]);
			}
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getSource().equals(cl)) {
			diacp.dispose();
		}
		else if (e.getSource().equals(ne)) {
			justshownext() ;
		}
		else if (e.getSource().equals(up)) {
			justshowup() ;
		}
		else if (e.getSource().equals(be)) {
			if (xxx == 1) {
				nowk = 0 ;
				presolve(new REC(1,1,chesssize)) ;
				xxx = 2 ;
			}
			if (!ok) {
				ok = true ;
				
			}
		}
		else if (e.getSource().equals(sp)) {
			ok = false ;
		}
	}

	private void justshowup() {
		// TODO Auto-generated method stub
		if (nowk < 0) return ;
		for (int i = 1 ; i <= chesssize ; ++ i) {
			for (int j = 1; j <= chesssize ; ++ j) {
				if (vis[i][j] == nowk-1) {
					chess[i][j].setBackground(Color.white);
				}
			}
		}
		nowk -- ;
	}

	static void justshownext() {
		// TODO Auto-generated method stub
		Color op = new Color(
		          (new Double(Math.random() * 128)).intValue() + 128,   
		          (new Double(Math.random() * 128)).intValue() + 128,   
		          (new Double(Math.random() * 128)).intValue() + 128);
		if (nowk <= k) {
			for (int i = 1 ; i <= chesssize ; ++ i) {
				for (int j = 1 ; j <= chesssize ; ++ j) {
					if (vis[i][j] == nowk) {
						chess[i][j].setBackground(op) ;
					}
				}
			}
			nowk ++ ;
		}
	}
}










~end~

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值