zoukankan      html  css  js  c++  java
  • UVa 11464

    解题报告:题目大意有一个N×N的矩阵,矩阵中的元素只有1或0,如果说对于一个矩阵,它的所有的点的上下左右的点的和是偶数,则称这个矩阵为偶数矩阵,现在给你一个任意的矩阵,要求的是如果要把这个矩阵变成偶数矩阵的话,最少需要将多少个点由1变成0,若不存在话,输出-1.(N<=15)

    这题如果枚举每个点的情况的话,虽然N最大只有15,但这样枚举的计算量依然非常大。但是我们可以发现,如果知道第一行的每一个点是什么样的,完全可以计算出下面的N-1行的每一个点。这样我们只要枚举第一行的每一个点的情况,这样的话时间复杂度就降为2^15,很明显快多了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int xxx[5]={0,-1,0,1,0};
     6 int yyy[5]={0,0,1,0,-1};
     7 const int MAX=0xffffff;
     8 int n,mep[16][16];
     9 int check(int s) {
    10     int mp[16],map[16][16],tot=0;
    11     memset(mp,0,sizeof(mp));
    12     memset(map,0,sizeof(map));
    13     for(int i=0;i<n;++i)
    14     if(s & (1<<i)) {
    15         if(mep[1][i+1]==0)
    16         tot++;
    17         mp[i+1]=1;
    18     }
    19     else if(mep[1][i+1]==1)
    20     return MAX;
    21     for(int i=1;i<=n;++i)
    22     map[1][i]=mp[i];
    23     for(int i=2;i<=n;++i)
    24     for(int j=1;j<=n;++j)
    25     map[i][j]=mep[i][j];
    26 
    27     for(int i=1;i<=n;++i)
    28     for(int j=1;j<=n;++j) {
    29         int sum=0;
    30         for(int k=1;k<=4;++k) {
    31             int xx=i+xxx[k];
    32             int yy=j+yyy[k];
    33             if(xx<=0||yy<=0||xx>n||yy>n)
    34             continue;
    35             sum+=map[xx][yy];
    36         }
    37         if(sum%2) {
    38             if(i!=n&&map[i+1][j]==0) {
    39                 map[i+1][j]=1;
    40                 tot++;
    41             }
    42             else return MAX;
    43         }
    44     }
    45     return tot;
    46 }
    47             
    48 int main( ) {
    49     int T;
    50     scanf("%d",&T);
    51     for(int l=1;l<=T;++l) {
    52         scanf("%d",&n);
    53         for(int i=1;i<=n;++i)
    54         for(int j=1;j<=n;++j)
    55         scanf("%d",&mep[i][j]);
    56         int ans=MAX;
    57         for(int s = 0;s < (1 << n ) ; ++s) //(1 << n )注意这个范围不能大也不能小 
    58         ans=min(check(s),ans);
    59         if(ans==MAX)
    60         ans=-1;
    61         printf("Case %d: %d
    ",l,ans);
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    C#8.0——异步流(AsyncStream)
    递归,循环,尾递归
    C#7.2——编写安全高效的C#代码
    Ocelot中文文档-Route
    Ocelot中文文档-Configuration
    Ocelot中文文档-Not Supported
    Ocelot中文文档-Getting Started
    .NET 单元测试的利剑——模拟框架Moq(简述篇)
    输入五个数字,按从大到小的顺序输出
    函数和方法的区别
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3139249.html
Copyright © 2011-2022 走看看