[枚举] POJ 3279

来源:互联网 发布:rabbitmq php amqp 编辑:程序博客网 时间:2024/06/03 17:09

看得我一脸懵逼。。。bfs感觉用不了,dfs又想不出来

查了一下发现所有的结果都和第一行有关(怎么想出来的orz)

所以枚举第一行所有情况


一堆二进制的操作只是优化

Fliptile POJ3279 二进制压缩枚举 解题报告


#include <cstring>#include <iostream>#include <queue>using namespace std;const int N = 16;//输入的矩阵,复制出来做翻转的矩阵,储存被翻转的位置的矩阵int g[ N ][ N ], t[ N ][ N ], f[ N ][ N ];int cnt, n, m;//四个方向int x[ 4 ] = {0, 0, -1, 1};int y[ 4 ] = {-1, 1, 0, 0};void flip ( int i, int j ) {        ++cnt, f[ i ][ j ] = 1;     //步数++,记录翻转点        t[ i ][ j ] = !t[ i ][ j ]; //翻转自己        for ( int k = 0; k < 4; ++k )                if ( i + x[ k ] > -1 && j + y[ k ] > -1 )                        t[ i + x[ k ] ][ j + y[ k ] ] ^= 1; //异或翻转}bool ok ( int k ) {        //初始化        cnt = 0;        memcpy ( t, g, sizeof ( t ) );        // 第一行的m列,        for ( int j = 0; j < m; ++j )                if ( k & ( 1 << ( m - 1 - j ) ) ) //找到k中翻转的列                        flip ( 0, j );        for ( int i = 1; i < n; ++i ) // 把2--n行上面一行的1全翻成0                for ( int j = 0; j < m; ++j )                        if ( t[ i - 1 ][ j ] )                                flip ( i, j );        for ( int j = 0; j < m; j++ ) // 考察最后一行能不能翻成功                if ( t[ n - 1 ][ j ] )                        return false;        return true;}int main () {        int ans, p;        while ( ~scanf ( "%d%d", &n, &m ) ) {                for ( int i = 0; i < n; ++i )                        for ( int j = 0; j < m; ++j )                                scanf ( "%d", &g[ i ][ j ] );                ans = n * m + 1, p = -1;                for ( int i = 0; i < ( 1 << m ); ++i ) // 枚举 2^m 种对第一行的翻转                        if ( ok ( i ) && cnt < ans )   // 记录最小的翻转次数                                ans = cnt, p = i;                memset ( f, 0, sizeof ( f ) );                if ( p >= 0 ) {                        ok ( p );                        for ( int i = 0; i < n; ++i )                                for ( int j = 0; j < m; ++j )                                        printf ( "%d%c", f[ i ][ j ], j < m - 1 ? ' ' : '\n' );                } else                        puts ( "IMPOSSIBLE" );        }        return 0;}


原创粉丝点击