俄罗斯方块是我很早之前做的模拟题, 题目在当时看来挺复杂, 现在看来也是挺简单了.
昨天看视频看到状压DP用二进制表示状态, 对这种思维方式印象深刻, 于是乎今天早上突然想起了用二进制表示曾经做过的俄罗斯方块题目.因为那道题有方块为1没方块为0. 觉得可行, 故试之.
结果没有想象中的代码少, 实现起来较为复杂. 不过还在用二进制表示的话, 空间复杂度和空间复杂度大大降低, 也不负这一番折腾.
最重要的是, 我又探索了了一种全新的数据表达方式.
我想这对思维的训练是有益的
这是用了二进制表示的代码, 期中用了位运算, 也算学以致用了: )
#include <iostream>
using namespace std;
int main()
{
int row[18] = {}, col, raw[4] = {}, loc;
for( int i = 0; i < 15; ++i ) {
for( int j = 0; j < 10; ++j ) {
cin >> col;
row[i] <<= 1;
if( col ) row[i]++;
}
}
for( int i = 0; i < 4; ++i ) {
for(int j = 0; j < 4; ++j ) {
cin >> col;
raw[i] <<= 1;
if( col ) raw[i]++;
}
}
cin >> loc;
for( int i = 4; i < 15; ++i ) {
for( int j = 3; j >= 0; --j ) {
if( row[i] & (raw[j] << (7 - loc))) {
for( int k = 3; k >= 0; --k ) {
row[i -1 +k - j] |= (raw[k] << (7 - loc));
}
break;
}
}
}
for( int i = 0; i < 15; ++i ) {
for( int j = 0; j < 10; ++j ) {
cout << ((row[i] & (1 << (9 - j))) ? 1 : 0) << ' ';
}
cout << endl;
}
}
再上此前使用的一般方法, 代码更短:
#include <iostream>
using namespace std;
int main(){
int line[16][11];
for(int i=1;i<=15;i++)
for(int j=1;j<=10;j++)
cin>>line[i][j];
int list[5][5];
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
cin>>list[i][j];
int q;
cin>>q;
for(int i=4;i>=1;i--)
for(int j=5;j<=15;j++)
for(int m=q;m<=q+4;m++){
if(list[i][m-q+1]&line[j][m]){
for(int g=1;g<=4;g++)
for(int h=1;h<=4;h++)
line[g+j-i-1][h+(q-1)]|=list[g][h];
goto flag;
}
}
flag : for(int i=1;i<=15;i++){
for(int j=1;j<=10;j++)
cout<<line[i][j]<<' ';
cout<<endl;
}
}