2012-A3-0016

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

题意:有一个L * W * H个立方体拼成的长方体,每个cube上有一个数字,每次可以将共面相邻两个数加减去一个相同的数,判断最后能否把所有cubes上的数变成0.

把每个格子(i,j,k)分成按i+j+k的奇偶性分成两类,如果两类的和相等就是可以,否则不行。

必要性:每次操作选取共面相邻的数,减去一个数,不改变两类的和的差。

充分性:如果两类的和相等,那么可以随机选取一组相邻的,都减去每类的和,那么这样每类的和就都是0了,

然后对于同一类中的两个数,随便找一条路径连接它们,它们的Manhattan距离必然是个偶数,沿路径正负交替操作加减同一个数,

可以实现同一类里面的2个数,分别+和-一个相同的数,由于每类的和是0,而每次这样的沿路径操作,都可以使这类中的数增加至少一个0,

这样最后可以分别把每类中的数都变成0.

{{{
#include<cstdio>
int main(){
    int l,w,h;
    for(bool ans;scanf("%d%d%d",&l,&w,&h)==3;puts(ans?"Yes":"No")){
        int a=0,b=0,t;
        for(int i=0;i<l;++i)
            for(int j=0;j<w;++j)
                for(int k=0;k<h;++k){
                    scanf("%d",&t);
                    if((i^j^k) &1){
                        a+= t;
                    }else{
                        b+=t;
                    }
                }
        ans = (a==b);
    }
}
}}}

题意:有一个L * W * H个立方体拼成的长方体,每个cube上有一个数字,每次可以将共面相邻两个数加减去一个相同的数,判断最后能否把所有cubes上的数变成0.

把每个格子(i,j,k)分成按i+j+k的奇偶性分成两类,如果两类的和相等就是可以,否则不行。

必要性:每次操作选取共面相邻的数,减去一个数,不改变两类的和的差。

充分性:如果两类的和相等,那么可以随机选取一组相邻的,都减去每类的和,那么这样每类的和就都是0了,

然后对于同一类中的两个数,随便找一条路径连接它们,它们的Manhattan距离必然是个偶数,沿路径正负交替操作加减同一个数,

可以实现同一类里面的2个数,分别+和-一个相同的数,由于每类的和是0,而每次这样的沿路径操作,都可以使这类中的数增加至少一个0,

这样最后可以分别把每类中的数都变成0.

#include<cstdio>
int main(){
    int l,w,h;
    for(bool ans;scanf("%d%d%d",&l,&w,&h)==3;puts(ans?"Yes":"No")){
        int a=0,b=0,t;
        for(int i=0;i<l;++i)
            for(int j=0;j<w;++j)
                for(int k=0;k<h;++k){
                    scanf("%d",&t);
                    if((i^j^k) &1){
                        a+= t;
                    }else{
                        b+=t;
                    }
                }
        ans = (a==b);
    }
}