/*
* youxi.cpp
*
* Created on: 2015年9月24日
* Author: sl
*/
/**
* 盖游戏板问题 算法问题实战策略
* 有一个H*W大小的游戏板,由黑白两种格子组成。现要用3个单位格子的L状板块把白色格子全部覆盖掉。板块可以自由旋转,但不能重叠覆盖黑色格子,或超出游戏版。
* 计算对给定游戏板有几种覆盖方法。
*/
#include<iostream>
#include<vector>
using namespace std;
/*
* 对当前格子的4种覆盖方法构成板块的3个格子的相对位置(dy,dx)
* 因为假定从最左上的格子开始覆盖。
*/
const int coverType[4][3][2] = {
{{0,0},{1,0},{0,1}},
{{0,0},{0,1},{1,1}},
{{0,0},{1,0},{1,1}},
{{0,0},{1,0},{1,-1}}
};
vector< vector<int> > board(3);
vector< vector<int> > board1(8);
/*
* 把board的格子(y,x)用第type种方法进行覆盖或删除已覆盖的板块。
* delta=1表示用板块覆盖,delta=-1则删除已覆盖的板块
* 如果不能正常覆盖(超出游戏板的边界,重叠、覆盖黑色格子)时,返回false值
*/
bool set(vector<vector<int> >& board, int y, int x, int type, int delta){
bool ok = true;
for(int i = 0;i<3;i++){
const int ny = y+coverType[type][i][0];
const int nx = x+coverType[type][i][1];
if(ny<0 || ny>=board.size() || nx<0 || nx>=board[0].size())
ok = false;
else if((board[ny][nx]+=delta)>1)
ok = false;
}
return ok;
}
/*
* 返回覆盖board中保存着的所有空格的方法总数。
* board[j][i]=1表示已被覆盖的格子或黑色格子
* board[j][i]=0表示未被覆盖的白色格子
*/
int cover(vector<vector<int> >& board){
int y = -1, x = -1;
for(int i = 0;i<board.size();i++){
for(int j = 0;j<board[i].size();j++)
if(board[i][j] ==0){
y = i;
x = j;
break;
}
if(y!=-1) break;
}
//初始部分:已覆盖所有的白色盒子,则返回1
if(y==-1)
return 1;
int ret = 0;
for(int type = 0;type<4;type++){
//如果能以type的形式覆盖board[y][x],就进行递归调用。
if(set(board, y, x ,type,1))
ret+=cover(board);
set(board, y,x,type,-1);
}
return ret;
}
int main(){
for(int i = 0;i<3;i++)
board[i].resize(7);
for(int i = 0;i<3;i++)
for(int j = 0;j<7;j++)
board[i][j] = 0;
board[0][0] = 1;
board[0][6] = 1;
board[1][0] = 1;
board[1][6] = 1;
board[2][0] = 1;
board[2][1] = 1;
board[2][4] = 1;
board[2][5] = 1;
board[2][6] = 1;
for(int i = 0;i<8;i++){
board1[i].resize(10);
}
for(int i = 0;i<8;i++){
for(int j = 0;j<10;j++){
board1[i][j] = 0;
}
}
for(int j = 0;j<10;j++){
board1[0][j] = 1;
}
for(int j = 0;j<10;j++){
board1[7][j] = 1;
}
for(int i = 1;i<=6;i++){
board1[i][0] = 1;
board1[i][9] = 1;
}
int result = cover(board);
int result1 = cover(board1);
cout<<result<<endl;
cout<<result1<<endl;
}
* youxi.cpp
*
* Created on: 2015年9月24日
* Author: sl
*/
/**
* 盖游戏板问题 算法问题实战策略
* 有一个H*W大小的游戏板,由黑白两种格子组成。现要用3个单位格子的L状板块把白色格子全部覆盖掉。板块可以自由旋转,但不能重叠覆盖黑色格子,或超出游戏版。
* 计算对给定游戏板有几种覆盖方法。
*/
#include<iostream>
#include<vector>
using namespace std;
/*
* 对当前格子的4种覆盖方法构成板块的3个格子的相对位置(dy,dx)
* 因为假定从最左上的格子开始覆盖。
*/
const int coverType[4][3][2] = {
{{0,0},{1,0},{0,1}},
{{0,0},{0,1},{1,1}},
{{0,0},{1,0},{1,1}},
{{0,0},{1,0},{1,-1}}
};
vector< vector<int> > board(3);
vector< vector<int> > board1(8);
/*
* 把board的格子(y,x)用第type种方法进行覆盖或删除已覆盖的板块。
* delta=1表示用板块覆盖,delta=-1则删除已覆盖的板块
* 如果不能正常覆盖(超出游戏板的边界,重叠、覆盖黑色格子)时,返回false值
*/
bool set(vector<vector<int> >& board, int y, int x, int type, int delta){
bool ok = true;
for(int i = 0;i<3;i++){
const int ny = y+coverType[type][i][0];
const int nx = x+coverType[type][i][1];
if(ny<0 || ny>=board.size() || nx<0 || nx>=board[0].size())
ok = false;
else if((board[ny][nx]+=delta)>1)
ok = false;
}
return ok;
}
/*
* 返回覆盖board中保存着的所有空格的方法总数。
* board[j][i]=1表示已被覆盖的格子或黑色格子
* board[j][i]=0表示未被覆盖的白色格子
*/
int cover(vector<vector<int> >& board){
int y = -1, x = -1;
for(int i = 0;i<board.size();i++){
for(int j = 0;j<board[i].size();j++)
if(board[i][j] ==0){
y = i;
x = j;
break;
}
if(y!=-1) break;
}
//初始部分:已覆盖所有的白色盒子,则返回1
if(y==-1)
return 1;
int ret = 0;
for(int type = 0;type<4;type++){
//如果能以type的形式覆盖board[y][x],就进行递归调用。
if(set(board, y, x ,type,1))
ret+=cover(board);
set(board, y,x,type,-1);
}
return ret;
}
int main(){
for(int i = 0;i<3;i++)
board[i].resize(7);
for(int i = 0;i<3;i++)
for(int j = 0;j<7;j++)
board[i][j] = 0;
board[0][0] = 1;
board[0][6] = 1;
board[1][0] = 1;
board[1][6] = 1;
board[2][0] = 1;
board[2][1] = 1;
board[2][4] = 1;
board[2][5] = 1;
board[2][6] = 1;
for(int i = 0;i<8;i++){
board1[i].resize(10);
}
for(int i = 0;i<8;i++){
for(int j = 0;j<10;j++){
board1[i][j] = 0;
}
}
for(int j = 0;j<10;j++){
board1[0][j] = 1;
}
for(int j = 0;j<10;j++){
board1[7][j] = 1;
}
for(int i = 1;i<=6;i++){
board1[i][0] = 1;
board1[i][9] = 1;
}
int result = cover(board);
int result1 = cover(board1);
cout<<result<<endl;
cout<<result1<<endl;
}