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代码:
碎片的给出是这么给的。
第一行一个数字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; }
相关文章推荐
- JAAS Authorization文档
- hdu 4950 Monster
- hdu 1203 01背包
- 星际争霸2编辑器 AI(转载)
- Hibernate 查询结果与数据库中的数据不一致
- POJ--2513 Colored Sticks
- checkbox与说明文字无法对齐的问题
- 设计模式学习
- redis安装使用配置
- weblogic热部署
- 剑指offer算法 java实现 二维数组中的查找
- 从零开始学android<ListView数据列表显示组件.二十一.>
- 编程点滴记录
- android 实例和分析
- 以另一种位图的思想来解决一道OJ题目
- (转)[老老实实学WCF] 第二篇 配置WCF
- Qt开发设置技巧
- Bresenham 画直线算法
- NSString的一些常用方法
- poj 1942 Paths on a Grid