zoukankan      html  css  js  c++  java
  • poj 3279 Fliptile

    Fliptile
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 4864   Accepted: 1862

    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变1或者由1变0)

    问至少需要多少次操作,所有的状态都为0

    如果有多组,输出字典序小的那一组.

    跟开关灯的那题相似.

    因为每个开关灯的动作还影响其他相邻灯的状态.所以对于这种题,一般思路是,先定住一部分,再由已知定住的这部分去确定其他部分.

    对于这道题而言

    首先我们可以很容易发现,操作数为偶数和为0是等价的.

    操作数为1和为奇数是等价的.

    对于这道题而言,我们可以首先枚举第一行的状态,一共有 2<<n  种.

    然后如果 a[i-1][j]为1,因为i-1行的状态已经确定,无法改变,所以能影响到a[i-1][j]的只有a[i][j]

    那么a[i][j]一定要操作一次

    最后判断最后一行是否都为0,如果为0,表示这种情况是合法的

    然后找到操作数最小的一组.

    字典序的话,只要是枚举的时候按照数的大小顺序就可以保证.

    学会了用memcpy函数.

    /*************************************************************************
        > File Name: code/2015summer/searching/D.cpp
        > Author: 111qqz
        > Email: rkz2013@126.com 
        > Created Time: Thu 23 Jul 2015 09:28:49 PM CST
     ************************************************************************/
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<map>
    #include<set>
    #include<queue>
    #include<vector>
    #include<stack>
    #define y0 abc111qqz
    #define y1 hust111qqz
    #define yn hez111qqz
    #define j1 cute111qqz
    #define tm crazy111qqz
    #define lr dying111qqz
    using namespace std;
    #define REP(i, n) for (int i=0;i<int(n);++i)  
    typedef long long LL;
    typedef unsigned long long ULL;
    const int N=20;
    int a[N][N],ans[N][N],op[N][N];
    int m,n;
    int dirx[10]={0,0,0,-1,1};
    int diry[10]={0,1,-1,0,0};
    int rec[N][N];
    void solve(int x,int y)
    {
        for ( int i = 0 ; i < 5 ; i++ )
        {
          int newx = x + dirx[i];
          int newy = y + diry[i];
          if (newx>=1&&newx<=m&&newy>=1&&newy<=n)
          {
            a[newx][newy]=a[newx][newy]^1;
          }
        }
    }
    bool on (int x,int y)
    {
        int res = a[x][y];
        for ( int i = 0 ; i < 5 ; i++ )
        {
          int newx = x + dirx[i];
          int newy = y + diry[i];
          if (newx>=1&&newx<=m&&newy>=1&&newy<=n)
          {
            res = res+op[newx][newy];
          }
        }
        return res&1;
    }
    int main()
    {
        cin>>m>>n;
        int mi = 9999999;
        memset(rec,0,sizeof(rec));
        for ( int i = 1 ; i <= m ; i++ )
        {
          for (int j = 1 ; j <= n ; j++)
          {
            cin>>a[i][j];
          }
        }
        bool flag = false;
        for ( int i = 0  ; i < (1<<n); i++ )   //枚举第一行的好改变情况
        {
            int tmp=i;
          int num=0;
          memset(op,0,sizeof(op));
            memset(ans,0,sizeof(ans));
          int k = n;
          while (tmp)
          {
            op[1][k]=tmp%2;
            if (op[1][k]==1) num++;
            tmp = tmp / 2;
            k--;
          }
    //      cout<<"********************"<<endl;
    //      for ( int i = 1 ; i <= n ; i++)
    //      {
    //        cout<<op[1][i]<<" ";
    //      }
    //      cout<<endl;
    //      cout<<"*************************"<<endl;
          for ( int j = 2 ; j <= m ; j++ )
          {
            for ( int k = 1 ; k <= n ; k++ )
            {
                if (on(j-1,k))
                {
                  op[j][k]=1;
                  num++;
                }
            }
          }
          bool ok = true;
          for ( int j = 1 ; j <= n ; j++ )
          {
            if (on(m,j))
            {
                ok=false;
                break;
            }
          }
          if (ok)
          {
            flag = true;
            if (num<mi)
            {
                mi = num;
                memcpy(rec,op,sizeof(op));
            }
          }
        }
        if (flag)
        {
          for ( int i = 1 ; i <= m ; i++ )
          {
            cout<<rec[i][1];
            for ( int j = 2 ; j <= n ; j++ )
            {
                cout<<" "<<rec[i][j];
            }
            cout<<endl;
          }
        }
        else
        {
          printf("IMPOSSIBLE
    ");
        }
        return 0;
    }
  • 相关阅读:
    自考 exec 7 3
    画函数图像
    Exec68
    applet main共存 五角星和五面形
    jcheckbox 用例
    JList 单击 ,双击例
    web性能优化(一)弱请求处理
    web性能优化(二)优化思维图
    算法之道左右旋转字符串
    腾讯微信面试题实现时间复杂度为O(1)的栈 20130226
  • 原文地址:https://www.cnblogs.com/111qqz/p/4672019.html
Copyright © 2011-2022 走看看