22 条题解

  • 3
    @ 2017-05-28 23:43:37

    #include<stdio.h>
    #include<math.h>
    #include<malloc.h>
    #include<string.h>
    #include<stdlib.h>
    int x[400][405];
    char y[5][21][21];
    int main()
    {
    int m,n,t;
    char s[100];
    scanf("%d%d%d",&n,&m,&t);
    scanf("\n");
    int i,j,k;
    for(k=0;k<t;++k)
    {
    for(i=0;i<n;++i)
    {
    for(j=0;j<m;++j)
    {
    scanf("%c",&y[k][i][j]);
    x[i*m+j][m*n+k]=y[k][i][j]-'0';
    }
    scanf("\n");
    }
    scanf("\n");
    }
    for(i=0;i<n;++i)
    for(j=0;j<m;++j)
    {
    x[i*m+j][i*m+j]=1;
    if(i>=1)
    x[i*m+j][i*m+j-m]=1;
    if(i>=2)
    x[i*m+j][i*m+j-m-m]=1;
    if(i<=n-2)
    x[i*m+j][i*m+j+m]=1;
    if(i<n-2)
    x[i*m+j][i*m+j+m+m]=1;
    if(j>0)
    x[i*m+j][i*m+j-1]=1;
    if(j<m-1)
    x[i*m+j][i*m+j+1]=1;

    }

    int dq=0,a=m*n;
    int pow[20]={1};
    for(i=1;i<20;++i)
    pow[i]=2*pow[i-1];

    for(i=0;i<a;++i)
    {
    int zj=0;
    for(j=dq;j<a;++j)
    if(x[j][i]==1)
    {
    ++zj;
    for(k=i;k<a+5;++k)
    {
    int bz;
    bz=x[dq][k];
    x[dq][k]=x[j][k];
    x[j][k]=bz;
    }
    break;
    }
    if(zj==0)
    continue;

    ++dq;
    for(j=dq;j<a;++j)
    {
    if(x[j][i]==0)
    continue;
    else
    for(k=i;k<a+5;++k)
    x[j][k]=x[j][k]^x[dq-1][k];

    }

    }
    for(k=0;k<t;++k)
    {
    int zj=0;
    for(i=dq;i<a;++i)
    if(x[i][a+k]!=0)
    ++zj;
    if(zj==0)
    printf("%d\n",pow[a-dq]);
    else
    printf("%d\n",0);

    }

    }

    直接解线性方程组似乎也可以做……

  • 2
    @ 2008-08-06 19:37:49

    之前经过1次修正后,仍然有4个测试点的标准输出有问题

    现在已经改正..

    因此造成大家的困扰深感抱歉...我自己对标程的不严谨是导致这个事件的主要原因..

    还是说声对不起..

  • 0
    @ 2009-11-01 15:42:12

    又一次,我将行列搞错

  • 0
    @ 2009-10-22 00:54:22

    两次AC.

    都是那个数据间要readln搞的.

  • 0
    @ 2009-10-07 16:13:02

    Accepted 有效得分:100 有效耗时:6473ms

    ___|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|__

    首先本人在此先强烈orz位运算

    再来本人谨代表广大的OIer感谢lolanv出了这种好题

    ---|---|---|---|---|---|↓↓↓↓↓↓↓↓↓↓---|---|--

    题解

    ___|\__|\__|\__|\__|\__|\__|_begin\___|\__|\__|\__|\__|\_|_

    本人觉得此题有两大技巧

    ①此题按列搜索是一大技巧(因为列与列之间改变状态有必然的关系

    example:

    第j列的第i个元素与目标状态不符合能用第j+1列的第i个元素

    来改变它,这样就可看为 ★确认第一列怎么变就能知道第二列怎么变了

    依次类推不难得出★ 只跟第一列怎么变 有关系了)

    ②用神奇的位运算来加速就不会超时了

    ___|\__|\__|\__|\__|\__|_ 核心___|\__|\__|\__|\__|\__|_

    p:=now;

    now:=now xor(now shr 1)xor(now shr 2)xor(now shl 1)xor(now shl 2)xor old xor a[j];

    now:=now and s;

    old:=p;

    ————————————

    用 二进制转化成十进制a[j] 来表示每列的目标状态

    now 代表当前列怎么改变 old代表前一列的状态

    s:=1 shl n-1能保证每一列不超出n位

    ___|\__|\__|( ^\__|^ ) \__|\___|\
    _|_

    不能自己想出来的话 深刻理解题解or代码也是有好处的

  • 0
    @ 2009-08-19 09:43:53

    晕死,让小衫给欺骗了。。。我心窝窝里的那个AC率啊!!!

  • 0
    @ 2009-08-05 20:43:26

    Accepted 有效得分:100 有效耗时:5471ms

    位运算+巧妙的题目处理方法。。

  • 0
    @ 2009-08-04 19:06:43

    两个数据之间忘了readln。。Wa了很多次

  • 0
    @ 2009-05-30 09:36:21

    看了楼下的程序,Orz位运算。

    其中i是在枚举第1列的修改状况(把整数转成二进制后,1表示修改该行第一列,0表示不修改)

    然后由于要达到目标状态,就会产生连锁反应(即按照修改方案修改后仍然无法达到目标,需要靠下一列修改这一行来满足目标)

    now:=now xor(now shr 1)xor(now shr 2)xor(now shl 1)xor(now shl 2)xor old xor f[j];

    到xor old为止是算出了当前列的状态,再xor f[j]来检查哪些行还需要没达到目标。

    只能解释这么多了,具体还要自己领悟……

  • 0
    @ 2008-11-25 19:13:35

    疯狂Orz位运算,太神奇了!!!

    我是小菜,今天才见识到位运算的神奇。。。

    program vijos1390;

    var n,m,t,tt,i,j,o,now,old,te,ans:longint;

    f:array[1..20]of longint;

    ch:char;

    begin

    readln(n,m,t);

    for tt:=1 to t do

    begin

    for i:=1 to 20 do f[i]:=0;

    for i:=1 to n do

    begin

    for j:=1 to m do

    begin

    read(ch);

    if ch='1' then f[j]:=f[j]+(1 shl(i-1));{将第j列的元素当做2进制化为十进制}

    end;

    readln;

    end;

    readln;

    o:=1 shl n-1;

    ans:=0;

    for i:=0 to o do

    begin

    now:=i;

    old:=0;

    for j:=1 to m do

    begin

    {now为第j列的变化情况,old为第(j-1)列变化情况}

    te:=now;

    now:=now xor(now shr 1)xor(now shr 2)xor(now shl 1)xor(now shl 2)xor old xor f[j];

    {如果第j列的第i个元素有变化,则j+1列也要做相应的变化(now shr 1表示变化第j+1列第i-1个元素,now shl 2表示变化第j+1列第i+2个元素,依此类推)如果第j-1列的第i个元素有变化,则j+1列的第i个元素也要变化(xor old)。。。}

    now:=now and o;{解决变化范围超出棋盘的情况}

    old:=te;

    end;

    if now=0 then inc(ans);{如果第n列无需变化,则答案加1}

    end;

    writeln(ans);

    end;

    end.

    只要理解标程,就会感到位运算的强大!

  • 0
    @ 2008-10-10 17:07:14

    囧。。我总共交了23次。。

    注意以下两点:

    1、n,m千万不要弄混,在此题中m是数组大小,n是元素的位数

    2、x:=f(x) and (1

  • 0
    @ 2008-08-06 17:09:37

    标程错了。。。。。。。。。。。。。。。。。。

    60 or 70 分的把

    (1 shl n)-1

    改成 (1 shl m)-1

    就行了。。。。。。。。。

    呵呵 (>-

  • 0
    @ 2008-08-07 14:54:28

    没关系,感谢所有改掉数据的人:)

    感谢lolanv出了这么好的一道题,虽然数据有问题

    呵呵~

  • 0
    @ 2008-08-06 20:32:33

    数据改过来了。。。

  • 0
    @ 2008-08-05 09:30:10

    为什么我会超时

  • 0
    @ 2008-08-04 10:46:34

    I don't know

  • 0
    @ 2008-08-04 07:48:55

    出这样的题,出题人到底是什么意思呢?

  • 0
    @ 2008-07-21 22:14:00

    小杉玩诈欺..

  • -1
    @ 2009-10-23 10:48:37

    编译通过...

    ├ 测试数据 01:答案正确... 650ms

    ├ 测试数据 02:答案正确... 634ms

    ├ 测试数据 03:答案正确... 666ms

    ├ 测试数据 04:答案正确... 1384ms

    ├ 测试数据 05:答案正确... 1431ms

    ├ 测试数据 06:答案正确... 1400ms

    ├ 测试数据 07:答案正确... 1462ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:7627ms

    终于过了 用个小号 不小心被封了 o(╯□╰)o

信息

ID
1390
难度
6
分类
其他 | 数学模拟 点击显示
标签
(无)
递交数
265
已通过
81
通过率
31%
被复制
2
上传者