zoukankan      html  css  js  c++  java
  • Uva 11464

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2459

    解题报告:题目的意思是,一个nXn 的矩阵,然后每个元素由0或1组成,然后现在要通过将矩阵中的某些0元素变为1来使矩阵的每一个元素的上下左右四个元素(如果存在的话)的值的和为偶数,现在问需要变动的最少的次数是多少?

    因为题目的数据量n <= 15,其中一种想法是枚举矩阵的每个元素变还是不变,但是15X15=225,这样时间复杂度将是2^225次方,所以,这样不行。但是我们可以发现如果把第一行的元素都确定下来,那么下面的每一行都可以由上一行推出来,所以,解法就出来了,我们可以每次枚举第一行的元素,然后通过第一行的元素将后面的元素都推出来,这样的话时间复杂度将是2^15,很明显就可以通过测试数据了。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 using namespace std;
      6 int add_x[4] = {-1,0,1,0};
      7 int add_y[4] = {0,1,0,-1};
      8 int matrix[20][20],temp[20][20];
      9 int changeto(int n,int m)     //一开始傻了,把这个返回值指定为bool型 
     10 {
     11     int f = 0,s = 0;
     12     memset(temp,0,sizeof(temp));
     13     for(int i = 0;i < m;++i)
     14     if(n & (1 << i))
     15     temp[0][i] = 1;
     16     else temp[0][i] = 0;
     17     for(int i = 0;i < m;++i)
     18     {
     19         if(temp[0][i] == 0 && matrix[0][i] == 1)
     20         return -1;
     21         else if(temp[0][i] == 1 && matrix[0][i] == 0)
     22         s++;
     23     }
     24     return s;
     25 }
     26 
     27 int solve(int n)
     28 {
     29     int maxn = 1 << n,ans = 0x7fffffff;
     30     for(int i = 0;i < maxn;++i)
     31     {
     32         int tt = changeto(i,n);
     33         if(tt != -1)        // 枚举第一行,然后其它行就可以由第一行推出 
     34         {
     35             for(int j = 1;j < n;++j)
     36             for(int k = 0;k < n;++k)
     37             temp[j][k] = matrix[j][k];
     38             int t = 0;
     39             for(int j = 0;j < n;++j)
     40             for(int k = 0;k < n;++k)
     41             {
     42                 int sum = 0;
     43                 for(int p = 0;p < 4;++p)    //计算出该点的上下左右四个位置的和 
     44                 {
     45                     int xx = j + add_x[p];
     46                     int yy = k + add_y[p];
     47                     if(xx >= 0 && xx < n && yy >= 0 && yy < n)
     48                     sum += temp[xx][yy];
     49                 }
     50                 if(sum & 1)          //如果四个位置的和为偶数则不用管,如果是奇数则... 
     51                 {
     52                     if(j >= n - 1)         //如果最后一行的出现奇数的话,没有办法了 
     53                     goto loop;
     54                     if(temp[j+1][k] == 1)  //如果下方的是1,不能把1变0,所以也没有办法 
     55                     goto loop;
     56                     else             //剩下的情况就是加起来的和是奇数,但可以将下面的那个数由0变1,其它位置的数一定是固定的 
     57                     {
     58                         temp[j+1][k] = 1;
     59                         t++;
     60                     }
     61                 }
     62             }
     63     //        if(t ==  1 || tt == 1)
     64     //        {
     65     //            printf("i = %d
    ",i);
     66     //            for(int j = 0;j < n;++j)
     67     //            for(int k = 0;k < n;++k)
     68     //            printf(k == n-1? "%d
    ":"%d ",temp[j][k]);
     69     //        }
     70         //    printf("t = %d tt = %d
    ",t,tt);
     71             ans = min(ans,t+tt);   // 别忘记加上第一行变的 
     72         }
     73 loop:       ;
     74     }
     75     return ans > 225? -1:ans;
     76 }
     77 /*int slove(int k,int n)
     78 {
     79     int fir = changeto(k,n);
     80     if(fir == -1)
     81     return 10000;
     82     for(int i = 1;i < n;++i)
     83     
     84     for(int j = 0;j < n;++j)
     85     temp[i][j] = matrix[i][j];
     86     int tot = 0;
     87     for(int i = 0;i < n;++i)
     88     for(int j = 0;j < n;++j)
     89     {
     90         int sum = 0;
     91         for(int p = 0;p < 4;++p)
     92         {
     93             int xx = i + add_x[p];
     94             int yy = j + add_y[p];
     95             if(xx >= 0 && xx < n && yy >= 0 && yy < n)
     96             sum += temp[xx][yy];
     97         }
     98         if(sum & 1)
     99         {
    100             if(i >= n - 1 || temp[i+1][j] == 1)
    101             return -1;
    102             if(temp[i+1][j] == 0)
    103             {
    104                 temp[i+1][j] = 1;
    105                 tot++;
    106             }
    107         }
    108     }
    109     return tot+fir;
    110 }*/
    111 int main()
    112 {
    113 //    freopen("in.txt","r",stdin);
    114     int n,T,kase = 1;
    115     scanf("%d",&T);
    116     while(T--)
    117     {
    118         scanf("%d",&n);
    119         for(int i = 0;i < n;++i)
    120         for(int j = 0;j < n;++j)
    121         scanf("%d",&matrix[i][j]);
    122         printf("Case %d: %d
    ",kase++,solve(n));
    123     }
    124     return 0;
    125 }
    View Code
  • 相关阅读:
    输入输出、基本运算符、流程控制
    Node学习6-fs模块
    Node学习5-events模块
    Node学习4-Buffer模块
    Node学习3-Path模块
    Node学习2-基础知识/HelloWorld/模块调用/global/process
    Node学习1-基本概念
    gulp/bower/less知识
    AngularJS学习1-基础知识
    JavaScript学习-类/原型链/class
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3653094.html
Copyright © 2011-2022 走看看