首页 > 其他分享 >kuangbin专题一 简单搜索 翻转(POJ-3279)

kuangbin专题一 简单搜索 翻转(POJ-3279)

时间:2023-04-14 20:58:12浏览次数:42  
标签:typedef int 3279 ++ POJ they kuangbin include 翻转

Fliptile

Time Limit: 2000MS Memory Limit: 65536K

Description

Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.

Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

Input

Line 1: Two space-separated integers: M and N
Lines 2..M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white

Output

Lines 1..M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.

Sample Input

4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1

Sample Output

0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0


题目大意

给一个 n * m 矩阵,矩阵中只有0和1两种值,现在我们需要将矩阵中所有的元素变为0。我们可以进行一种翻转的操作,若选定(i,j)翻转,同时须将其上、下、左、右四个方向进行翻转(翻转即0变成1,1变成0)。问步数最少且字典序最小的方案。输出一个矩阵,1代表(i,j)被翻转,0代表不被翻转。



解题思路

这道题很容易让人联想到一道题 ———— 费解的开关,其实几乎完全一样的递推做法,只不过需要输出具体的方案,只需要另开一个数组存储具体方案即可。题目中要求字典序最小,因为是从上往下递推的,所以只需要记录步数最短的第一个方案就可以了。

/*   一切都是命运石之门的选择  El Psy Kongroo  */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<cmath>
#include<functional>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;
typedef pair<double, double> pdd;
typedef pair<string, pii> psi;
typedef __int128 int128;
#define x first
#define y second
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;

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

const int N = 16;
int g[N][N], backup[N][N];   //当前图状态  图状态备份
int ans[N][N], tmp[N][N];    //记录答案  当前翻转方案
int n, m;
int minstep = 1e9;
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};

//翻转
void turn(int x, int y){
    g[x][y] ^= 1;
    for(int k = 0; k < 4; k ++ ){
        int nx = x + dx[k], ny = y + dy[k];
        if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
        g[nx][ny] ^= 1;
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    cin >> n >> m;
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < m; j ++ ) 
            cin >> g[i][j];

    //状态压缩  枚举状态  二进制为1表示第一行次列进行翻转
    for(int sta = 0; sta < (1 << m); sta ++ ){
        memset(tmp, 0, sizeof(tmp));
        memcpy(backup, g, sizeof(g));

        int step = 0;    //得到第一行的状态
        for(int k = 0; k < m; k ++ ){
            if(sta >> k & 1){
                tmp[0][k] = 1;
                turn(0, k);
                step ++ ;
            }
        }

        for(int i = 0; i < n - 1; i ++ ){   //查看0-n-2行的状态,第(i + 1, j)处若为1需翻转其下面的位置
            for(int j = 0; j < m; j ++ ){
                if(g[i][j] == 1){
                    tmp[i + 1][j] = 1;
                    turn(i + 1, j);
                    step ++ ;
                }
            }
        }

        bool all_dark = true;          //查看最后一行是否全为0
        for(int i = 0; i < m; i ++ )
            if(g[n - 1][i]){
                all_dark = false;
                break;
            }

        if(all_dark && step < minstep){ //更新答案
            memcpy(ans, tmp, sizeof(tmp));
            minstep = step;
        }

        memcpy(g, backup, sizeof(backup));
    }

    if(minstep == 1e9){
        cout << "IMPOSSIBLE" << endl;
        return 0;
    }
    
    for(int i = 0; i < n; i ++ ){
        for(int j = 0; j < m; j ++ )
            cout << ans[i][j] << ' ';
        cout << endl;
    }

    return 0;
}

标签:typedef,int,3279,++,POJ,they,kuangbin,include,翻转
From: https://www.cnblogs.com/MAKISE004/p/17319916.html

相关文章

  • poj 2182
    LostCowsPOJ-2182与这题一样BuyTickets-POJ2828-VirtualJudge(csgrandeur.cn)题意:有1~NN个数字,这N个数字的顺序是打乱的,从第二个数字开始给你它的前面有多少个数字比他小思路:输入的数字都要加一,然后我们从后往前遍历,在线段树中如果左子树的sum‘>sum,则进入左子......
  • kuangbin专题一 简单搜索 抓住那头牛(POJ-3278)
    CatchThatCowTimeLimit:2000MS MemoryLimit:65536KTotalSubmissions:210291 Accepted:63838DescriptionFarmerJohnhasbeeninformedofthelocationofafugitivecowandwantstocatchherimmediately.HestartsatapointN(0≤N≤100,000)on......
  • kuangbin专题一 简单搜索 棋盘问题(POJ-1321)
    棋盘问题TimeLimit:1000MS MemoryLimit:10000KTotalSubmissions:125427 Accepted:56304Description在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘......
  • kuangbin专题一 简单搜索 地牢大师(POJ-2251)
    DungeonMasterTimeLimit:1000MS MemoryLimit:65536KTotalSubmissions:92499 Accepted:31990DescriptionYouaretrappedina3Ddungeonandneedtofindthequickestwayout!Thedungeoniscomposedofunitcubeswhichmayormaynotbefilledwith......
  • POJ 1780 Code (欧拉回路+非递归版dfs)
    题目地址:POJ1780还是求序列的欧拉回路。只不过这题有两坑。第一坑是用数字来当点的话,会MLE,因为每个数字可以连10条边,100w条边会MLE,即使用vector也会TLE。这题可以用边来记录,对于n为1时直接输出,然后后面的,比如12,23这两个点就用边权值为123来表示这两个点,这样就把点和边的范围......
  • HDU 1116 && POJ 1386 Play on Words(欧拉路径)
    按字母来建边,每个单词的首字母和尾字母加边。先判断是否连通,然后判断每个字母的入度和出度不能出现差的绝对值大于2,然后入度和出度差的绝对值为1的不能超过两个。就可以形成欧拉路径代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include......
  • POJ 1753 Flip Game (高斯消元)
    题目地址:POJ1753第三次做这道题了。第一次是刚学搜索的时候做的,第二次是刚学状态压缩枚举的时候做的,这次是刚学高斯消元、、每次都做得很艰辛。。目测这题应该没了别的方法了吧。。。。。。这题除了高斯消元外还需要枚举变元,方法是状态压缩枚举,然后返回去迭代解方程。代码如下:#inc......
  • POJ 1830 开关问题 (高斯消元)
    题目地址:POJ1830高斯消元第一发。一个地方逻辑判断出现了失误,调了一下午啊。。。通过高斯消元来找矩阵的秩,然后2^(自由元的数量)就是答案。因为对于每个自由元,都有0和1两种状态可选。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#includ......
  • POJ 2337 Catenyms (欧拉回路+并查集)
    题目地址:POJ2337这题跟POJ1386差不多,只不过这题多一个输出路径而已。按字母来建边,每个单词的首字母和尾字母加边。先判断是否连通,然后判断每个字母的入度和出度不能出现差的绝对值大于2,然后入度和出度差的绝对值为1的不能超过两个。就可以形成欧拉路径代码如下:#include<iostream......
  • POJ 1905 Expanding Rods (二分+计算几何+精度处理)
    题目地址:POJ1905用二分枚举h,然后判断弧长是否符合条件。重点还是在精度问题上,具体看代码吧。。#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include......