zoj 2678 The Toy of Flandre Scarlet

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4941


题目大意:

有一个l*w*h的立方体,可以分为l*w*h个单位立方体,每个单位立方体上有一个非负数。

相邻的两个立方体可以同时减去或加上一个整数任意次。

求是否可以使所有立方体上的数为零。


题目思路:

首先可以确定的是,(*)要减去的数是所有的数之和

并且要对两个相邻的单位方块进行操作,假设某一个方块的数大于与它相邻的所有方块之和,如果要使这个方块能被减为0,要如何做到呢?

那么显然与它相邻的数要向其他地方借数。

为了方便我们构造如下图:

a1 a2 a3 a4

a5 a6 a7 a8

a9 b1 b2 b3

设a2 > a1+a3+a6

那么显然a1,a3,a6要向a5,b1,a7,a4借数,才能使得a2被减为0,

而被借的数,显然要承担的值就为a2 -(a1+a3+a6),即值被转移了。

通过上面的例子我们可以知道,设某一个值的坐标为(i,j,k),那么该值可以向所有坐标为(x+y+z)且

(x+y+z)%2==(i+j+k)%2的转移值

由(*)可知,不管对值怎么进行转移,要减去多少数始终只会减去多少数

也就是说只要满足sum[(x+y+z)%2==0] = sum[(x+y+z)%2==1]即可


代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

#define ll __int64
#define ls rt<<1
#define rs ls|1
#define lson l,mid,ls
#define rson mid+1,r,rs
#define middle (l+r)>>1
#define clr_all(x,c) memset(x,c,sizeof(x))
#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))
#define eps (1e-8)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#pragma comment(linker, "/STACK:102400000,102400000")
template <class T> T _max(T x,T y){return x>y? x:y;}
template <class T> T _min(T x,T y){return x<y? x:y;}
template <class T> T _abs(T x){return (x < 0)? -x:x;}
template <class T> T _mod(T x,T y){return (x > 0)? x%y:((x%y)+y)%y;}
template <class T> void _swap(T &x,T &y){T t=x;x=y;y=t;}
template <class T> void getmax(T& x,T y){x=(y > x)? y:x;}
template <class T> void getmin(T& x,T y){x=(x<0 || y<x)? y:x;}
int TS,cas=1;
const int M=60000+5;
int l,w,h,c[2],a;

void run(){
	int i,j,k;
	c[0]=c[1]=0;
	for(i=0;i<l;i++)
		for(j=0;j<w;j++)
			for(k=0;k<h;k++)
				scanf("%d",&a),c[(i+j+k)&1]+=a;
	printf("%s\n",c[0]==c[1]? "Yes":"No");
}

void preSof(){
}

int main(){
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    preSof();
    //run();
    while((~scanf("%d%d%d",&l,&w,&h))) run();
    //for(scanf("%d",&TS);cas<=TS;cas++) run();
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值