您的位置:首页 > 其它

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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: