题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3647
题意:给你十个俄罗斯方块,问你能否拼成指定长宽的矩形,方块下落的顺序是严格确定的,后下落的方块不能落在先下落的方块之下。
分析:这个题的方法跟 POJ 1020 Anniversary Cake 完全一致。具体分析参见 http://blog.csdn.net/lyy289065406/article/details/6683250
每个俄罗斯方块都是由更小的小方格拼成的, 可以用一个一维数组来记录每一列已经摞上了多少个小方格。DFS遵循底部放满原则,如果可以恰好和已存在的方块实现无缝拼接才往上放,否则回溯。
细心一些,把情况考虑清楚即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 char tet[20]; //记录方块的下降次序 6 int box[45]; //把方块分成小格子,记录每列有多个小格子 7 int m, n; 8 9 bool DFS( int cur ) 10 { 11 if ( cur == 10 ) return true; 12 13 switch( tet[cur] ) 14 { 15 case 'I' : 16 for ( int i = 0; i < n; i++ ) 17 { 18 if ( box[i] + 4 <= m ) //判断能不能竖着放 19 { 20 box[i] += 4; 21 if ( DFS( cur + 1 ) ) return true; 22 box[i] -= 4; 23 } 24 if ( i + 3 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i + 2] == box[i + 3] && box[i] + 1 <= m ) //能不能横着放 25 { 26 for ( int j = i; j < i + 4; j++ ) ++box[j]; 27 if ( DFS( cur + 1 ) ) return true; 28 for ( int j = i; j < i + 4; j++ ) --box[j]; 29 } 30 } 31 break; 32 33 case 'O': 34 for ( int i = 0; i < n; i++ ) 35 { 36 if ( i + 1 < n && box[i] == box[i + 1] && box[i] + 2 <= m ) 37 { 38 box[i] += 2; 39 box[i + 1] += 2; 40 if ( DFS( cur + 1 ) ) return true; 41 box[i] -= 2; 42 box[i + 1] -= 2; 43 } 44 } 45 break; 46 47 case 'L' : 48 for ( int i = 0; i < n; i++ ) 49 { 50 if ( i + 1 < n && box[i] + 3 <= m && box[i] == box[i + 1] ) //正着放L 51 { 52 box[i] += 3; 53 box[i + 1] += 1; 54 if ( DFS( cur + 1 ) ) return true; 55 box[i] -= 3; 56 box[i + 1] -= 1; 57 } 58 59 if (i + 2 < n && box[i] + 1 == box[i + 1] && box[i + 1] == box[i + 2] && box[i] + 2 <= m && box[i + 1] + 1 <= m ) //顺时针旋转90° 60 { 61 box[i] += 2; 62 box[i + 1] += 1; 63 box[i + 2] += 1; 64 if ( DFS( cur + 1 ) ) return true; 65 box[i] -= 2; 66 box[i + 1] -= 1; 67 box[i + 2] -= 1; 68 } 69 70 if (i + 1 < n && box[i] + 1 <= m && box[i + 1] + 3 <= m && box[i + 1] + 2 == box[i] ) //顺时针旋转180° 71 { 72 box[i] += 1; 73 box[i + 1] += 3; 74 if ( DFS( cur + 1 ) ) return true; 75 box[i] -= 1; 76 box[i + 1] -= 3; 77 } 78 79 if (i + 2 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i + 2] + 2 <= m ) //顺时针旋转270° 80 { 81 box[i] += 1; 82 box[i + 1] += 1; 83 box[i + 2] += 2; 84 if ( DFS(cur + 1) ) return true; 85 box[i] -= 1; 86 box[i + 1] -= 1; 87 box[i + 2] -= 2; 88 } 89 90 } 91 break; 92 93 case 'J' : 94 for ( int i = 0; i < n; i++ ) 95 { 96 if (i + 1 < n && box[i] == box[i + 1] && box[i + 1] + 3 <= m ) //0 97 { 98 box[i] += 1; 99 box[i + 1] += 3; 100 if ( DFS(cur + 1) ) return true; 101 box[i] -= 1; 102 box[i + 1] -= 3; 103 } 104 if (i + 2 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i] + 2 <= m) //90 105 { 106 box[i] += 2; 107 box[i + 1] += 1; 108 box[i + 2] += 1; 109 if ( DFS( cur + 1 ) ) return true; 110 box[i] -= 2; 111 box[i + 1] -= 1; 112 box[i + 2] -= 1; 113 } 114 if (i + 1 < n && box[i] + 2 == box[i + 1] && box[i] + 3 <= m && box[i + 1] + 1 <= m ) //180 115 { 116 box[i] += 3; 117 box[i + 1] += 1; 118 if ( DFS( cur + 1 ) ) return true; 119 box[i] -= 3; 120 box[i + 1] -= 1; 121 } 122 if (i + 2 < n && box[i] == box[i + 1] && box[i + 2] + 1 == box[i + 1] && box[i] + 1 <= m && box[i + 2] + 2 <= m) //270 123 { 124 box[i] += 1; 125 box[i + 1] += 1; 126 box[i + 2] += 2; 127 if ( DFS(cur + 1) ) return true; 128 box[i] -= 1; 129 box[i + 1] -= 1; 130 box[i + 2] -= 2; 131 } 132 } 133 break; 134 135 case 'Z' : 136 for ( int i = 0; i < n; i++ ) 137 { 138 if (i + 2 < n && box[i + 2] == box[i + 1] && box[i + 1] + 1 == box[i] && box[i] + 1 <= m && box[i + 1] + 2 <= m ) //0 139 { 140 box[i] += 1; 141 box[i + 1] += 2; 142 box[i + 2] += 1; 143 if ( DFS( cur + 1 ) ) return true; 144 box[i] -= 1; 145 box[i + 1] -= 2; 146 box[i + 2] -= 1; 147 } 148 if (i + 1 < n && box[i] + 1 == box[i + 1] && box[i] + 2 <= m && box[i + 1] + 2 <= m) //90 149 { 150 box[i] += 2; 151 box[i + 1] += 2; 152 if ( DFS( cur + 1 ) ) return true; 153 box[i] -= 2; 154 box[i + 1] -= 2; 155 } 156 } 157 break; 158 159 case 'S' : 160 for ( int i = 0; i < n; i++ ) 161 { 162 if (i + 2 < n && box[i] == box[i + 1] && box[i + 1] + 1 == box[i + 2] && box[i + 1] + 2 <= m && box[i + 2] + 1 <= m ) //0 163 { 164 box[i] += 1; 165 box[i + 1] += 2; 166 box[i + 2] += 1; 167 if ( DFS(cur + 1) ) return true; 168 box[i] -= 1; 169 box[i + 1] -= 2; 170 box[i + 2] -= 1; 171 } 172 if (i + 1 < n && box[i + 1] + 1 == box[i] && box[i] + 2 <= m && box[i + 1] + 2 <= m ) //90 173 { 174 box[i] += 2; 175 box[i + 1] += 2; 176 if ( DFS(cur + 1) ) return true; 177 box[i] -= 2; 178 box[i + 1] -= 2; 179 } 180 } 181 break; 182 183 case 'T' : 184 for ( int i = 0; i < n; i++ ) 185 { 186 if ( i + 2 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i + 1] + 2 <= m ) //0 187 { 188 box[i] += 1; 189 box[i + 1] += 2; 190 box[i + 2] += 1; 191 if ( DFS( cur + 1 ) ) return true; 192 box[i] -= 1; 193 box[i + 1] -= 2; 194 box[i + 2] -= 1; 195 } 196 197 if ( i + 1 < n && box[i] + 1 == box[i + 1] && box[i] + 3 <= m ) //90 198 { 199 box[i] += 3; 200 box[i + 1] += 1; 201 if ( DFS( cur + 1 ) ) return true; 202 box[i] -= 3; 203 box[i + 1] -= 1; 204 } 205 if ( i + 2 < n && box[i] == box[i + 2] && box[i + 1] + 1 == box[i] && box[i + 1] + 2 <= m ) //180 206 { 207 box[i] += 1; 208 box[i + 1] += 2; 209 box[i + 2] += 1; 210 if ( DFS( cur + 1 ) ) return true; 211 box[i] -= 1; 212 box[i + 1] -= 2; 213 box[i + 2] -= 1; 214 } 215 216 if ( i + 1 < n && box[i + 1] + 1 == box[i] && box[i + 1] + 3 <= m ) //270 217 { 218 box[i] += 1; 219 box[i + 1] += 3; 220 if ( DFS( cur + 1 ) ) return true; 221 box[i] -= 1; 222 box[i + 1] -= 3; 223 } 224 } 225 break; 226 } 227 return false; 228 } 229 230 int main() 231 { 232 while ( scanf( "%d%d", &n, &m ), n || m ) 233 { 234 for ( int i = 0; i < 10; i++ ) 235 { 236 getchar(); 237 tet[i] = getchar(); 238 } 239 240 memset( box, 0, sizeof(box) ); 241 242 if ( DFS(0) ) puts("Yes"); 243 else puts("No"); 244 } 245 return 0; 246 }