您的位置:首页 > 其它

UVA387

2014-08-16 14:36 99 查看
题目的意思就是给你一些碎片,这些碎片能不能组成一个4 × 4 的正方形,碎片要全用上,而且不能重复。

碎片的给出是这么给的。

第一行一个数字n 给出有几个碎片 接下去是n个碎片描述。

每个碎片描述,先是两个数字,表示这个碎片占了几行几列,



2 3

111

101 表示两行三列,形状就是1的地方是有的0的地方是没有的,举例的这个碎片就是题目中A的样子。

这题不需要减枝,只要一个坐标一个坐标回溯,满足就放进去,最后碎片全用上,并且铺满4 × 4了,就输出就行。只要输出一个。。

有注意的点,

01

01

11

01

这块碎片,在判断时要小心并不是,它只需要还剩一列就可以放了,我一开始有判断条件如果要放位置的列数,加上图形的列数大于4就不能放,这是错的,应该还要减掉前面位0的列数,

另外就是要判断碎片全都用上。

AC代码:

#include<iostream>
#include<string>
using namespace std;

const int N = 5;
struct node {
int row;
int col;
string pos
;
}p
;
int num;
int vis

;
int use
;
bool ok;
void init () {
for (int i = 0 ; i < N ;i++) {
for (int j = 0; j < N ;j++) {
vis[i][j] = 0;
p[i].pos[j] = "";
}
use[i] = 0;
}
ok = false;

}
bool judge (int x, int y ,int k) {
int a = 0;
int b = 0;
int nl;
for (int i = 0 ; i < p[k].col ; i++) {
if (p[k].pos[0][i] == '1') {
nl = i;
break;
}
}
if (x + p[k].row >  4 || y - nl + p[k].col  > 4 || y - nl < 0)
return false;
for (int i = x ; i < p[k].row + x ;i++) {
for (int j = y - nl ; j < p[k].col + y - nl ;j++) {
if(p[k].pos[a][b++] == '1' && vis[i][j])
return false;
if(b == p[k].col) {
a++;
b = 0;
}
}
}
return true;
}
void set(int x ,int y ,int k) {
int a = 0 ;
int b = 0 ;
int nl;
for (int i = 0 ; i < p[k].col ; i++) {
if (p[k].pos[0][i] == '1') {
nl = i;
break;
}
}
for (int i = x ; i < p[k].row + x ;i++) {
for (int j = y - nl ; j < p[k].col + y -nl ;j++) {
if(p[k].pos[a][b++] == '1')
vis[i][j] = k + 1;
if( b == p[k].col ) {
b = 0;
a++;
}
}
}
}
void back (int x ,int y , int k) {
int a = 0 ;
int b = 0 ;
int nl;
for (int i = 0 ; i < p[k].col ; i++) {
if (p[k].pos[0][i] == '1') {
nl = i;
break;
}
}
for (int i = x ; i < p[k].row + x ;i++) {
for (int j = y - nl; j < p[k].col + y -nl ;j++) {
if (p[k].pos[a][b++] == '1')
vis[i][j] = 0;
if(b == p[k].col) {
a++;
b = 0;
}
}
}
}
bool yes () {
for (int i = 0 ; i < 4 ;i++) {
for (int j = 0 ; j < 4 ; j++) {
if (!vis[i][j])
return false;
}
}
for (int i = 0 ; i < num ; i++) {
if (use[i] == 0)
return false;
}
return true;
}
void dfs(int x ,int y) {
if (ok == true) {
return ;
}
if(yes()) {
ok = true;
for (int i = 0 ; i < 4 ;i++) {
for (int j = 0  ; j < 4 ;j++) {
cout << vis[i][j];
}
cout <<endl;
}
return;
}
for (int i = x ; i < 4 ;i++) {
for (int j = y ; j < 4 ;j++) {
if (vis[i][j]) {
if (j == 3)
y = 0;
continue;
}
for (int k = 0 ; k < num;k++) {
if(judge(i,j,k) && !use[k]) {
set(i,j,k);
use[k] = 1;
dfs(i + (j + 1) / 4, (j + 1) % 4);
if (ok == true)
return;
back(i,j,k);
use[k] = 0;
}
if (k == num - 1)
return;
}
if (j == 3)
y = 0;
}
}
return ;
}
int main () {
int T = 0;
while (cin >> num && num) {
if (T++)
cout << endl;
init();
for (int i = 0 ; i < num ; i++) {
cin >> p[i].row >> p[i].col;
for (int j = 0 ; j < p[i].row ; j++) {
cin >> p[i].pos[j];
}
}
dfs (0,0);
if (!ok)
cout <<"No solution possible" <<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: