poj 2965 11/14

来源:互联网 发布:linux3.0内核源码分析 编辑:程序博客网 时间:2024/06/03 21:30

题目大意:有一把样式为四行四列矩阵的锁,矩阵上的每个单元都是一个开关,开关规则如下:

      1.如果你拨动了这个开关,这个开关的状态改变(开->关)(关->开)

          2.这行和这列的开关也改变。

只有在所有单元打开后锁才能打开。

求最少打开开关的步数和方案。


思路1:id-dfs 显然不过。


思路2:我很有信心地把1753的代码改了改交上去,然后超时了居然超时了!!!


思路3(来自网络):如果想要让坐标(x,y)的单元状态改变并且不改变其他状态的话,则必须要把x行和y列的开关全都按一边。


原来:                        按a0                       行全按                   列全按

a0   b0   c0   d0        -a0  -b0 -c0 -d0     -a0      不变           -a0        不变

a1   b1   c1   d1        -a1  不变               不变    全负             不变     不变

a2   b2   c2   d2        -a2

a3   b3   c3   d3        -a3


这种思路我只能说数学真重要。

接下来一样的道理,如果有开关是关闭着的,则同行同列需要按的次数+1

在计算按的次数时,n次和n-2次是一样的,所以只记录按过奇数次的单元。

答案得手。


<span style="font-size:18px;color:#000000;"><strong>#include <iostream>#include <cstring>#define INF 999999using namespace std;char table[5][5];int main(){char val=0;int total=0;for (int i=1;i<=4;++i)  for (int j=1;j<=4;++j)    {    cin>>val;    if(val=='+')    {    for (int k=1;k<=4;++k)    {    table[i][k]++;    table[k][j]++;}table[i][j]--;    }}for (int i=1;i<=4;++i)  for (int j=1;j<=4;++j)   total+=table[i][j]%2;cout<<total<<endl;for (int i=1;i<=4;++i)  for (int  j=1;j<=4;++j)  {  if(table[i][j]%2)  cout<<i<<' '<<j<<endl;    }return 0;   }</strong></span>


 




0 0