zoukankan      html  css  js  c++  java
  • 金币阵列问题

      有m*n(m <=100,n <=100)个金币在桌面上排成一个m行n 列的金币阵列。每一枚金币或正面朝上或背面朝上。用数字表示金币状态,0表示金币正面朝上,1 表示背面朝上。

      金币阵列游戏的规则是: (1)每次可将任一行金币翻过来放在原来的位置上;

      (2)每次可任选2 列,交换这2 列金币的位置。

       编程任务:给定金币阵列的初始状态和目标状态,编程计算按金币游戏规则,将金币阵列从初始状态变换到目标状态所需的最少变换次数。

    Input

      输入数据有多组数据。第1行有1 个正整数k,表示有k 组数据。每组数据的第1 行有2 个正整数m 和n。以下的m行是金币阵列的初始状态,每行有n 个数字表示该行金币的状态,0 表示金币正面朝上,1 表示背面朝上。接着的m行是金币阵列的目标状态。

    Output

      将计算出的最少变换次数按照输入数据的次序输出。相应数据无解时输出-1。

    代码是别人的,感觉写的很好。写这个博客,主要是想要重温一下思路。

    枚举1~m中,每一列为第一列的情况,

    //从1~n行,找出不满足的行,进行一次变换

    //若是所枚举的这一列可以成功根据规则转换成目标矩阵,则,此时的矩阵与原矩阵的差别只会在列序上

    此时,从i=2 列(第二列)开始与目标矩阵的第i列进行比较,

    若不同,寻找本矩阵中第j列(就= i+1~m)是否有与目标矩阵的第i列相同的,若有,且 本矩阵第j列!= 目标矩阵第j列,则,进行一次列变换

    //若是找不到符合条件的列,则所枚举的这一列为第一列是不可能按所给规则变换到目标矩阵的

      1 #include<stdio.h>
      2 
      3 const int inf = 99999;
      4 const int N = 101;
      5 
      6 int a[N][N],b[N][N],temp[N][N]; //a存储初始矩阵,b为目标状态矩阵
      7 int n,m;
      8 int need;//需要变换次数
      9 
     10 void ChangeL(int x,int y)//变换列
     11 {
     12     if(x==y)return;
     13     int i;
     14     for(i=1;i<=n;i++)
     15     {
     16         int tt=temp[i][y];
     17         temp[i][y]=temp[i][x];
     18         temp[i][x]=tt;
     19     }
     20     need++;
     21 }
     22 
     23 void ChangeH(int x)//变换行
     24 {
     25     int i;
     26     for(i=1;i<=m;i++)
     27     {
     28         temp[x][i]^=1;
     29     }
     30 }
     31 
     32 
     33 bool Same(int x,int y) //判断列是否满足条件
     34 {
     35     int i;
     36     for(i=1;i<=n;i++)
     37         if(b[i][x]!=temp[i][y])return false;
     38     return true;
     39 }
     40 
     41 
     42 int main()
     43 {
     44     int tests;
     45     scanf("%d",&tests); //数据组数
     46     
     47     while(tests--)
     48     {
     49         scanf("%d%d",&n,&m); //n行,m列
     50         int i,j;
     51         for(i=1;i<=n;i++)
     52             for(j=1;j<=m;j++)
     53             {
     54                 scanf("%d",&a[i][j]);
     55             }
     56 
     57             for(i=1;i<=n;i++)
     58                 for(j=1;j<=m;j++)
     59                     scanf("%d",&b[i][j]);
     60 
     61             int k;
     62             int ans=inf; //ans存储最终答案,初始值为无穷大
     63 
     64 
     65             for(k=1;k<=m;k++)//枚举各列为第一列
     66             {
     67                 for(i=1;i<=n;i++)
     68                     for(j=1;j<=m;j++)
     69                         temp[i][j]=a[i][j];
     70                 need=0;
     71                 ChangeL(1,k);
     72 
     73 
     74                 //不满足的行,进行一次变换
     75                 for(i=1;i<=n;i++)
     76                 {
     77                     if(temp[i][1]!=b[i][1])//该行不满足条件
     78                     {
     79                         ChangeH(i);//变换行
     80                         need++;
     81                     }
     82                 }
     83 
     84 
     85                 bool find;
     86                 for(i=1;i<=m;i++)//检查每列是否满足条件
     87                 {
     88                     find=false;
     89                     if(Same(i,i))
     90                     {
     91                         find=true;
     92                         continue;
     93                     }
     94                     for(j=i+1;j<=m;j++)//寻找temp中与b的i列相同的列
     95                     {
     96                         if(Same(i,j))//temp 的 j列于b的i列相同
     97                         {
     98                             if(Same(j,j))continue;//temp的j列与b的j列相同
     99                             ChangeL(i,j);//交换temp的i,j列
    100                             find=true;
    101                             break;
    102                         }
    103                     }
    104                     if(find==false)//找不到该列对应列
    105                     {
    106                         break;
    107                     }
    108                 }
    109 
    110 
    111                 if(find==true&&need<ans)
    112                     ans=need;
    113             }
    114 
    115 
    116             if(ans<inf)
    117                 printf("%d\n",ans);
    118             else
    119                 printf("-1\n");
    120     }
    121     return 0;
    122 }

    参考资料:http://blog.csdn.net/sftxlin/article/details/7282645

  • 相关阅读:
    Leetcode 1. Two Sum (Python)
    视觉机器学习------KNN学习
    anaconda新建虚拟环境安装各个依赖包
    Matconvnet安装
    argparse模块
    Matconvnet笔记(一)
    Ubuntu14.04下如何安装TensorFlow
    springboot2+freemarker简单使用
    mongodb安装4.0(rpm)
    检测web界面不能访问后重启
  • 原文地址:https://www.cnblogs.com/hxsyl/p/2945169.html
Copyright © 2011-2022 走看看