ZOJ_3364_Black and White(巧算方格图形面积)
2013-07-24 09:01
316 查看
Black and White
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit Status
Description
Consider an infinite chessboard. Introduce a coordinate system on it in such a way that chessboard cells are unit squares with integer corner coordates. Let the cells be colored black and white like on the standard chessboard, let the cell with bottom left
corner at (0,0) be colored black.
Somebody has drawn a closed polyline on the board. The vertices of the polyline are in the corners of the cells and its sides are parallel to the coordinate axes. It's interesting, what is the number of black and white cells inside the polyline. Find that
out.
Input
The first line of the input file contains n --- the number of vertices of the polyline (1 ≤ n ≤ 50000). The following n lines contain the coordinates of the vertices in counter-clockwise order. Coordinates are integer and do not
exceed 109 by their absolute values. Polyline has no self-intersections and no self-touchings.
There are multiple cases. Process to the end of file.
Output
Output two numbers: b and w --- the number of black and white cells inside the polyline repectively.
Sample Input
Sample Output
题型:计算几何
题意:
在一个类似于国际象棋的坐标系中,给出一系列逆时针摆布的点的坐标,这些点之间相连成一个多边形,多边形的边平行于X轴或者Y轴,求出多边形内黑色方块与白色方块的个数。
分析:
在比赛时打算,将几何体分成一层一层的宽为1,长度为每一层两边最大x之差的矩形,然后通过一层一层的来算得到结果,结果发现如果是长的像城墙一样的几何体就不管用了。
后来,考虑到所有的点是按逆时针输入的,想可以将这些点遍历一遍,先来分析一下几何体在X轴上方的情况,对于两个点(x1,y1),(x2,y2),若y1==y2,可以计算出(x1,y1)、(x2,y2)、(x1,0)、(x2,0)这四个点围成的矩形中黑色与白色方块的个数,当点的方向是从右向左市,就加上其矩形的黑色块数与白色块数;当点的走向是从左向右时,就减去其矩形的黑色块数与白色块数,最终的结果就是要求的答案。这样的想法是对的,可是我一直在WA。
下附WA代码:
无奈之下,只好另选思路再写,遍历一下这些点,用前一个点与原点围成的矩形的面积减去后一个点与原点围成的矩形的面积,遍历到最后就可以得出这个几何图形的总面积了,然后在求出黑色方块的个数即可。
AC代码:
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
Submit Status
Description
Consider an infinite chessboard. Introduce a coordinate system on it in such a way that chessboard cells are unit squares with integer corner coordates. Let the cells be colored black and white like on the standard chessboard, let the cell with bottom left
corner at (0,0) be colored black.
Somebody has drawn a closed polyline on the board. The vertices of the polyline are in the corners of the cells and its sides are parallel to the coordinate axes. It's interesting, what is the number of black and white cells inside the polyline. Find that
out.
Input
The first line of the input file contains n --- the number of vertices of the polyline (1 ≤ n ≤ 50000). The following n lines contain the coordinates of the vertices in counter-clockwise order. Coordinates are integer and do not
exceed 109 by their absolute values. Polyline has no self-intersections and no self-touchings.
There are multiple cases. Process to the end of file.
Output
Output two numbers: b and w --- the number of black and white cells inside the polyline repectively.
Sample Input
12 1 0 2 0 2 1 3 1 3 2 2 2 2 3 1 3 1 2 0 2 0 1 1 1
Sample Output
1 4
题型:计算几何
题意:
在一个类似于国际象棋的坐标系中,给出一系列逆时针摆布的点的坐标,这些点之间相连成一个多边形,多边形的边平行于X轴或者Y轴,求出多边形内黑色方块与白色方块的个数。
分析:
在比赛时打算,将几何体分成一层一层的宽为1,长度为每一层两边最大x之差的矩形,然后通过一层一层的来算得到结果,结果发现如果是长的像城墙一样的几何体就不管用了。
后来,考虑到所有的点是按逆时针输入的,想可以将这些点遍历一遍,先来分析一下几何体在X轴上方的情况,对于两个点(x1,y1),(x2,y2),若y1==y2,可以计算出(x1,y1)、(x2,y2)、(x1,0)、(x2,0)这四个点围成的矩形中黑色与白色方块的个数,当点的方向是从右向左市,就加上其矩形的黑色块数与白色块数;当点的走向是从左向右时,就减去其矩形的黑色块数与白色块数,最终的结果就是要求的答案。这样的想法是对的,可是我一直在WA。
下附WA代码:
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; int x[56789]; int y[56789]; long long b,w; int main(){ int n; while(~scanf("%d",&n)){ b=0; w=0; for(int i=0;i<n;i++){ scanf("%d%d",&x[i],&y[i]); } for(int i=1;i<n;i++){ if(x[i]<x[i-1]&&y[i]==y[i-1]){ if(y[i]>=0){ if((x[i-1]-x[i])*y[i]%2==0){ b+=(x[i-1]-x[i])*y[i]/2; w+=(x[i-1]-x[i])*y[i]/2; } else{ b+=(x[i-1]-x[i])*y[i]/2; w+=(x[i-1]-x[i])*y[i]/2; if(((y[i]%2==1)&&(x[i]%2==0))||((y[i]%2==0)&&(x[i]%2==1))) b++; else w++; } } else{ if((x[i-1]-x[i])*(-y[i])%2==0){ b-=(x[i-1]-x[i])*(-y[i])/2; w-=(x[i-1]-x[i])*(-y[i])/2; } else{ b-=(x[i-1]-x[i])*(-y[i])/2; w-=(x[i-1]-x[i])*(-y[i])/2; if((((-y[i])%2==1)&&(x[i]%2==0))||(((-y[i])%2==0)&&(x[i]%2==1))) w--; else b--; } } } else if(x[i]>x[i-1]&&y[i]==y[i-1]){ if(y[i]>=0){ if((x[i]-x[i-1])*y[i]%2==0){ b-=(x[i]-x[i-1])*y[i]/2; w-=(x[i]-x[i-1])*y[i]/2; } else{ b-=(x[i]-x[i-1])*y[i]/2; w-=(x[i]-x[i-1])*y[i]/2; if(((y[i]%2==1)&&(x[i-1]%2==0))||((y[i]%2==0)&&(x[i-1]%2==1))) b--; else w--; } } else{ if((x[i]-x[i-1])*(-y[i])%2==0){ b+=(x[i]-x[i-1])*(-y[i])/2; w+=(x[i]-x[i-1])*(-y[i])/2; } else{ b+=(x[i]-x[i-1])*(-y[i])/2; w+=(x[i]-x[i-1])*(-y[i])/2; if((((-y[i])%2==1)&&(x[i-1]%2==0))||(((-y[i])%2==0)&&(x[i-1]%2==1))) w++; else b++; } } } //cout<<"b="<<b<<" "<<"w="<<w<<endl; } if(x[n-1]>x[0]&&y[0]==y[n-1]){ if(y[0]>=0){ if((x[n-1]-x[0])*y[0]%2==0){ b+=(x[n-1]-x[0])*y[0]/2; w+=(x[n-1]-x[0])*y[0]/2; } else{ b+=(x[n-1]-x[0])*y[0]/2; w+=(x[n-1]-x[0])*y[0]/2; if(((y[0]%2==1)&&(x[0]%2==0))||((y[0]%2==0)&&(x[0]%2==1))) b++; else w++; } } else{ if((x[n-1]-x[0])*(-y[0])%2==0){ b-=(x[n-1]-x[0])*(-y[0])/2; w-=(x[n-1]-x[0])*(-y[0])/2; } else{ b-=(x[n-1]-x[0])*(-y[0])/2; w-=(x[n-1]-x[0])*(-y[0])/2; if((((-y[0])%2==1)&&(x[0]%2==0))||(((-y[0])%2==0)&&(x[0]%2==1))) w--; else b--; } } } else if(x[n-1]<x[0]&&y[0]==y[n-1]){ if(y[0]>=0){ if((x[0]-x[n-1])*y[0]%2==0){ b-=(x[0]-x[n-1])*y[0]/2; w-=(x[0]-x[n-1])*y[0]/2; } else{ b-=(x[0]-x[n-1])*y[0]/2; w-=(x[0]-x[n-1])*y[0]/2; if(((y[0]%2==1)&&(x[n-1]%2==0))||((y[0]%2==0)&&(x[n-1]%2==1))) b--; else w--; } } else{ if((x[0]-x[n-1])*(-y[0])%2==0){ b-=(x[0]-x[n-1])*(-y[0])/2; w-=(x[0]-x[n-1])*(-y[0])/2; } else{ b-=(x[0]-x[n-1])*(-y[0])/2; w-=(x[0]-x[n-1])*(-y[0])/2; if((((-y[0])%2==1)&&(x[n-1]%2==0))||(((-y[0])%2==0)&&(x[n-1]%2==1))) b--; else w--; } } //cout<<"b="<<b<<" "<<"w="<<w<<endl; } printf("%lld ",b); printf("%lld\n",w); } return 0; } /* 4 1 1 4 1 4 4 1 4 4 0 1 0 -2 3 -2 3 1 4 0 0 -3 0 -3 -3 0 -3 */
无奈之下,只好另选思路再写,遍历一下这些点,用前一个点与原点围成的矩形的面积减去后一个点与原点围成的矩形的面积,遍历到最后就可以得出这个几何图形的总面积了,然后在求出黑色方块的个数即可。
AC代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; int n; int xn,yn,xp,yp; int x,y; long long sum; long long b; int odd(int x) { if(x>=0) return (x+1)/2; else return x/2; } int even(int x){ return x-odd(x); } void fun(){ sum+=(long long)xp*yp-(long long)xn*yn; b+=(long long)odd(xp)*odd(yp)+(long long)even(xp)*even(yp)-((long long)odd(xn)*odd(yn)+(long long)even(xn)*even(yn)); return; } int main(){ while(~scanf("%d",&n)){ sum=0; b=0; scanf("%d%d",&x,&y); xp=x; yp=y; n--; while(n--){ scanf("%d%d",&xn,&yn); if(yn==yp) fun(); xp=xn; yp=yn; } xn=x; yn=y; if(yn==yp) fun(); sum-=b; printf("%lld ",llabs(b)); printf("%lld\n",llabs(sum)); } return 0; }
相关文章推荐
- ZOJ 2997 Black and White
- POJ 3364 Black and white painting 再想想
- poj 3364 Black and white painting
- poj 3364 Black and white painting
- Poj 3364 Black and white painting
- UVa 11231 - Black and white painting
- HDU - 5113 Black And White 搜索+剪枝 ( 2014ACM/ICPC亚洲区北京站-重现赛(感谢北师和上交))
- hdu 5583 Kingdom of Black and White
- Codeforces Round #158 (Div. 2)D. Black and White Tree(搜索 + 思维)
- HDU 3911 Black And White(线段树区间合并+lazy操作)
- HDU 5113 Black And White(dfs)
- zoj 2165 Red and Black
- HDU-3911Black and White
- hdu 3911 Black And White
- 杂码系列之 Black and white painting hdoj 1802
- hdu3911 Black And White(线段树区间合并)
- HDU 3633 Black and white(插头DP)
- hdu 5113 Black And White
- hdu 3911 Black and White
- hdu 5583 Kingdom of Black and White