zoukankan      html  css  js  c++  java
  • Fliptile [POJ3279] [开关问题]

    题意

    给定一张n*m的方格图,有1,0两种数字,每次可以选取一个十字进行翻转,1变成0,0变成1,问最少需要翻转几次,使它全部变成0,全部如果有重复的,按字典序最小的进行输出;

    输入

    第一行n,m

    下面一个矩阵,代表方格图

    输出

    按矩阵原格式输出是否需要翻转

    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

    分析

    这道题也是一个开关问题,但是相对于上一题(我博客的上一题[POJ3276]),显然这是个二维的矩阵了,调整一个会对四面八方有影响,这样就不能确定地做一件操作的。我们要想着如何变成一个有固定操作规律的方法。看数据也许能启发我们,因为N只有15,可能跟搜索有关。我们有以往的例子,在列用dfs枚举,在行就可以直接操作/DP。针对这个题,发现如果第一行确定了,第一行的某个值确定了,就只有它正下方的数字影响它,这样就可以确定下一行的翻转情况。以此类推,检验最后一行即可。

    代码

     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define RG register int
    11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
    12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
    13 #define ll long long
    14 #define inf (1<<29)
    15 #define maxn 20
    16 using namespace std;
    17 int n,m,ans=inf;
    18 int num[maxn][maxn],gra[maxn][maxn],tag[maxn][maxn],rec[maxn],an[maxn][maxn];
    19 inline int read()
    20 {
    21     int x=0,f=1;char c=getchar();
    22     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    23     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    24     return x*f;
    25 }
    26 
    27 inline void modify(int i,int j){gra[i][j]^=1,gra[i-1][j]^=1,gra[i][j-1]^=1,gra[i+1][j]^=1,gra[i][j+1]^=1;}
    28 int p;
    29 void judge()
    30 {
    31     memset(tag,0,sizeof(tag));
    32     rep(i,1,n)rep(j,1,m)     gra[i][j]=num[i][j];
    33     rep(i,1,m)    if(rec[i])    tag[1][i]=1,modify(1,i);
    34     rep(i,2,n)
    35         rep(j,1,m)
    36             if(gra[i-1][j])
    37                 modify(i,j),tag[i][j]=1;
    38     rep(j,1,m)    if(gra[n][j])    return;
    39     int sum=0;
    40     rep(i,1,n)rep(j,1,m)    sum+=tag[i][j];
    41     if(sum<=ans)    
    42     {
    43         ans=sum;
    44         rep(i,1,n)rep(j,1,m)    an[i][j]=tag[i][j];
    45     }
    46 }
    47 
    48 void dfs(int step)
    49 {
    50     if(step>m){judge();return;}
    51     rec[step]=1;dfs(step+1);
    52     rec[step]=0;dfs(step+1);
    53 }
    54 
    55 int main()
    56 {
    57     n=read(),m=read();
    58     rep(i,1,n)rep(j,1,m) num[i][j]=read();
    59     dfs(1);
    60     if(ans==inf)puts("IMPOSSIBLE");
    61     else    {rep(i,1,n){rep(j,1,m) printf("%d ",an[i][j]);puts("");}}
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    成熟到优秀的瓶颈问题
    今天我们为什么不成功
    将HTML标签变为小写
    2010世界杯 排阵型 猜比分
    又一款 jQuery 头图切换形式
    整理下工作环境的相应资源
    prototype 的ajax
    即时点选的菜单
    如何禁止一个输入框输入
    基于jQuery的仿FLASH 菜单
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9291356.html
Copyright © 2011-2022 走看看