棋盘覆盖问题 |
Time Limit: 1000ms, Special Time Limit:2500ms,Memory Limit:32768KB |
Total submit users: 65, Accepted users:26 |
Problem 10432 : No special judgement |
Problem description |
在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
|
Input |
输入文件第一行是一个整数T,表示有多少组测试数据,接下来是T组测试数据,共2T行,每组第一行为整数n,是2的n次幂(1<=n<=64),表示棋盘的大小为n*n,第二行是两个整数,代表特殊方格所在行号和列号。 |
Output |
先输出“CASE:i,然后按样例输出。数据间用制表符隔开(‘t’),每行最后一个数据后无制表符。 |
Sample Input |
2
2
0 0
8
2 2
|
Sample Output |
CASE:1
0 1
1 1
CASE:2
3 3 4 4 8 8 9 9
3 2 2 4 8 7 7 9
5 2 0 6 10 10 7 11
5 5 6 6 1 10 11 11
13 13 14 1 1 18 19 19
13 12 14 14 18 18 17 19
15 12 12 16 20 17 17 21
15 15 16 16 20 20 21 21
|
Judge Tips |
要求遍历顺序按从左到右,从上到下。 |
Problem Source |
qshj |
package hunan;
import java.util.Arrays;
import java.util.Scanner;
/**
* @description HUNAN OJ 10432 棋盘覆盖问题
* @technique 递归分治
* @version 1.0
* @date 20120821
* @time 09:47
* @author Alex
* @note 程序运行正确,但是提交不上去。查了好久,还是不行,最后果断放弃了。
* 先放这吧。有时间再看。
*/
public class HuNan10432_20120820_0 {
private static int num = 1; //记录填充的次数。
private static int initX; //特殊点 x 坐标。
private static int initY; //特殊点 x 坐标。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int [][] map;
int count, n, cas = 0;
count = in.nextInt();
while(count-->0){
n = in.nextInt();
num = 1;
initX = in.nextInt();
initY = in.nextInt();
map = new int[n][n];
init(map);
map[initX][initY] = 0;
solve(map, 0, 0, map.length, map.length,initX,initY);
System.out.println("CASE:" + (++cas));
show(map);
}
}
/**
*
* @param map 棋盘。
* @param i 棋盘左上角 x 坐标
* @param j 棋盘左上角 y 坐标
* @param x 棋盘右下角 x 坐标
* @param y 棋盘右下角 y 坐标
* @param initX 特殊点 x 坐标。
* @param initY 特殊点 x 坐标。
* @note 程序还没进行优化。好多重复代码。今天太累。不管了。
*/
private static void solve(int [][] map, int i, int j, int x, int y, int initX, int initY){
if(i==x-1&&j==y-1){ //递归结束条件。 当棋盘只剩一个方格时束。
return;
}
int i1,i2,i3,i4,j1,j2,j3,j4,x1,x2,x3,x4,y1,y2,y3,y4;
i1 = i;j1 = j;x1 = (x+i)>>1;y1 = (y+j)>>1; //左上角。
i2 = i;j2 = (y+j)>>1; x2 = (x+i)>>1; y2 = y; //右上角。
i3 = (x+i)>>1; j3 = j; x3 = x; y3 = (y+j)>>1; //左下角。
i4 = x1; j4 = y1; x4 = x; y4 = y;//右下角。
if(isIn(i1,j1,x1,y1,initX,initY)){ //判断特殊点是否在左上角区域
map[x2-1][j2] = num; //右上。 //填充。
map[i4][j4] = num;//右下。
map[i3][y3-1] = num; //左下。
++num;
solve(map,i1,j1,x1,y1,initX,initY);//如果在左上角。刚特殊点坐标不变。
solve(map,i2,j2,x2,y2,x2-1,j2); //右上角特殊点坐标更新为刚刚在这一区域填充的点。
solve(map,i3,j3,x3,y3,i3,y3-1); //同上。
solve(map,i4,j4,x4,y4,i4,j4); //同上。
}else if(isIn(i2,j2,x2,y2,initX,initY)){ ////判断特殊点是否在右上角区域
map[x1-1][y1-1] = num; //左上。
map[i4][j4] = num;//右下。
map[i3][y3-1] = num; //左下。
++num;
solve(map,i1,j1,x1,y1,x1-1,y1-1);
solve(map,i2,j2,x2,y2,initX,initY);
solve(map,i3,j3,x3,y3,i3,y3-1);
solve(map,i4,j4,x4,y4,i4,j4);
}else if(isIn(i3,j3,x3,y3,initX,initY)){ //判断特殊点是否在左下角区域
map[x2-1][j2] = num; //右上。
map[i4][j4] = num;//右下。
map[x1-1][y1-1] = num; //左上。
++num;
solve(map,i1,j1,x1,y1,x1-1,y1-1);
solve(map,i2,j2,x2,y2,x2-1,j2);
solve(map,i3,j3,x3,y3,initX,initY);
solve(map,i4,j4,x4,y4,i4,j4);
}else if(isIn(i4,j4,x4,y4,initX,initY)){ //判断特殊点是否在右下角区域
map[x1-1][y1-1] = num; //左上。
map[i3][y3-1] = num; //左下。
map[x2-1][j2] = num; //右上。
++num;
solve(map,i1,j1,x1,y1,x1-1,y1-1);
solve(map,i2,j2,x2,y2,x2-1,j2);
solve(map,i3,j3,x3,y3,i3,y3-1);
solve(map,i4,j4,x4,y4,initX,initY);
}
}
/**
*
* @param i 棋盘左上角 x 坐标
* @param j 棋盘左上角 y 坐标
* @param x 棋盘右下角 x 坐标
* @param y 棋盘右下角 y 坐标
* @param initX 特殊点 x 坐标。
* @param initY 特殊点 y 坐标。
* @return 如果特殊点在棋盘区域内,返回 true ,否则返回 false;
*/
private static boolean isIn(int i, int j, int x, int y, int initX, int initY){
if(initX>=i && initY>=j && initX