poj 2965 The Pilots Brothers' refrigerator 高斯消元法 暑假第二题

文章中的名词理解;

1.翻转:+到-或-到+

2。操作:即为对其行和列的点翻转

1.首先得明白,对一个点只能进行奇次操作,即操作一次。取反原理

2.证明:要使一个为'+'的符号变为'-',必须其相应的行和列的操作数为奇数;可以证明,如果'+'位置对应的行和列上每一个位置都进行一次操作,则整个图只有这一'+'位置的符号改变,其余都不会改变.

思路如下:红色点将为接下来进行的操作点

假如为  :     -     -      +     -

                    -    -      -      -

                    -    -      -    -

                    -    -      -      -

  若对第一行的每一个点都进行操作,第一行每一个点都翻转4次,等价于没反转。

   但是2,3,4行都翻转了一次,故变为+;有

                     -    -      +     -

                     +  +     +     +

                    +   +     +     +

                   +    +    +     +

则剩2,3,4的红色点还没操作,操作后:

       2,3,4行的每一个点(除红色点)都翻转一次;有

                 

                     -     -      +     -

                    -    -      +    -

                    -    -      +   -

                    -    -      +    -

3列的每一个点都翻转3次;有

                    

                     -     -      -   -

                    -    -      -   -

                    -    -      -   -

                    -    -      -    -

      故证明

设置一个4*4的整型数组,初值为零,用于记录每个点的操作数,那么在每个'+'上的行和列的的位置都加1,得到结果模2(因为一个点进行偶数次操作的效果和没进行操作一样,这就是楼上说的取反的原理),然后计算整型数组中为1的个数并记录其位置。
代码如下:0ms
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char a[5][5];
int b[5][5];
int c[60];
int main()
{
    int i,j,p,q;
    memset(b,0,sizeof(b));
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='+')
                {
           for(p=0;p<4;p++)
            b[i][p]++;
           for(q=0;q<4;q++)
            b[q][j]++;
           b[i][j]--;
                }
        }
    }
    int k=0;
    int start=0;
    for(i=0;i<4;i++)
    {
        for(j=0;j<4;j++)
        {
            int l=b[i][j];
            l%=2;
            if(l==1)
            {
                k++;
                c[start++]=i;
                c[start++]=j;
            }
        }
    }
    cout<<k<<endl;
    for(i=0;i<start;i+=2)
    {
        cout<<c[i]+1<<' '<<c[i+1]+1<<endl;
    }
    return 0;
}



    



         

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值