这道题给我最大的启示是:不要乱用ceil函数,在位数接近16位的情况下!
这道题只需要算一种颜色的格子,然后就得出这个公式:白色格子数=原来白色格子的总数-第一个格子白色总数-第二个格子白色总数+重叠部分白色的总数+第一个格子的面积-重叠部分的总面积
再有就是在算重叠部分的时候左下坐标取max,右上坐标取min
在计算面积的时候由于精度失真不能用ceil,于是在左下角为白色且格子个数为奇数的时候总面积/2+1,其余时候/2.
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll cal(int x1,int y1,int x2,int y2) { if( (x1+y1)%2==0&&1LL*(x2-x1+1)*(y2-y1+1)%2==1 ) { return 1LL*(x2-x1+1)*(y2-y1+1)/2+1; } else { return 1LL*(x2-x1+1)*(y2-y1+1)/2; } } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int x3,y3,x4,y4; scanf("%d%d%d%d",&x3,&y3,&x4,&y4); ll res=cal(1,1,m,n)-cal(x1,y1,x2,y2)-cal(x3,y3,x4,y4)+1LL*(x2-x1+1)*(y2-y1+1); if( x2<x3||x4<x1||y1>y4||y2<y3 ); else { ll x5=max(x1,x3),y5=max(y1,y3),x6=min(x2,x4),y6=min(y2,y4); res+=( cal(x5,y5,x6,y6)-(x6-x5+1)*(y6-y5+1) ); } printf("%lld %lld ",res,1LL*n*m-res); } }