可以将圆变成4个1/4圆看看有没有什么新发现哈!
用0-1统治世界!
这个程序比较烂,但总算编出来了.
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define PI 3.1415926
typedef struct coordinate
{
int x;
int y;
} coord;
main()
{
int i,j,k,num,maxx,maxy,minx,miny,distant,c1=0,c2=0,c3=0,c4=0;
double area=0;
coord cor[15],checkpoint[225];
printf("Please input the num of the circles:");
scanf("%d",&num);
printf("Now enter the coordinate of the circles:");
for(i=0;i<num;i++)
scanf("%d%d",&cor[i].x,&cor[i].y);
maxx=minx=cor[0].x;
for(i=1;i<num;i++)
{
if(cor[i].x<minx)
minx=cor[i].x;
if(cor[i].x>maxx)
maxx=cor[i].x;
}
maxy=miny=cor[0].y;
for(i=1;i<num;i++)
{
if(cor[i].y<miny)
miny=cor[i].y;
if(cor[i].y>maxy)
maxy=cor[i].y;
}
distant=maxy-miny>maxx-minx?maxy-miny+2:maxx-minx+2;
i=0;
for(k=0;k<distant;k++)
for(j=0;j<distant;j++)
{
checkpoint[i].x=minx-1+j;
checkpoint[i++].y=maxy+1-k;
}
for(k=0;k<distant*distant;k++)
{
for(i=0;i<num;i++)
{
c1+=(checkpoint[k].x==cor[i].x&&checkpoint[k].y==cor[i].y);/*检测点是否在坐标上*/
c2+=(checkpoint[k].x+1==cor[i].x&&checkpoint[k].y==cor[i].y);/*正右边*/
c3+=(checkpoint[k].x+1==cor[i].x&&checkpoint[k].y-1==cor[i].y);/*右下方*/
c4+=(checkpoint[k].x==cor[i].x&&checkpoint[k].y-1==cor[i].y); /*正下方*/
}
if(c1&&c3||c2&c4)
area+=1;
else if(c1&&c2||c3&&c2||c1&&c4||c3&&c4)
area+=sqrt(3.0)/4+PI/6;
else if(c1||c2||c3||c4)
area+=PI/4;
c1=c2=c3=c4=0;
}
printf("The area is %.4lf",area);
getch();
}
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define Pi 3.1415926535898
double area[]={0,0,0,0,0};
typedef unsigned short ui2;
typedef unsigned long ui4;
typedef struct
{
short x,y;//圆心坐标;
}
Center;
typedef struct
{
ui4 xy; //xy=10000*x+y;
ui2 No; //(1/4)圆的编号
}
Quarter;
double Area(Quarter* p)
{
int ix=0;
switch(p->No)
{
case 15:
case 14:
case 13:
case 11:
case 7: ix++;
case 10:
case 5: ix++;
case 12:
case 9:
case 6:
case 3: ix++;
case 8:
case 4:
case 2:
case 1: ix++;
}
return area[ix];
}
int main(void)
{
Center*pC,*CT;
Quarter*p,*QT,temp;
short NUM;//单位圆的总数
short x,y;//圆心的直角坐标
short x1,x2,y1,y2;//极限值
short i; ui2 j;
double sum=0;//NUM个圆所占总面积
printf("Number of circles = ");
scanf("%d",&NUM);
for(i=1; i<=NUM; i++)
{
printf("circle %d's center(x,y) = ",i);
scanf("%d%*c%d",&x,&y);
if(i==1)
{
pC=CT=(Center*)malloc(NUM*sizeof(Center));
//为节省篇幅,我们假设内存申请是成功的。
x1=x2=x;
y1=y2=y;
}
else
{
if(x<x1)x1=x;//搜索x的极小
if(y<y1)y1=y;//搜索y的极小
if(x>x2)x2=x;//搜索x的极大
if(y>y2)y2=y;//搜索y的极大
}
pC->x=x;pC->y=y;pC++;
}
//下面为1/4圆申请较多的内存,仍默认获得成功:
p=QT=(Quarter*)malloc(4*NUM*sizeof(Quarter));
//下面是把NUM个圆切成4*NUM个Quarter(即1/4圆)
//STEP 1:
//为了让结构体Quarter正常工作,进行坐标平移,
//移动量为:新坐标=旧坐标+(x1+1,y1+1)
//显然这样做不会影响面积计算
for(pC=CT,i=0;i<NUM;i++,pC++)
pC->x+=x1+1,pC->y+=y1+1;
//STEP 2:
//设圆心位于(x,y)则它的
//第1个1/4圆位于以(x,y)和(x+1,y+1)为顶点的正方形内
//第2个1/4圆位于以(x-1,y)和(x,y+1)为顶点的正方形内
//第3个1/4圆位于以(x-1,y-1)和(x,y)为顶点的正方形内
//第4个1/4圆位于以(x,y-1)和(x+1,y)为顶点的正方形内
//下面记录的时候以左下方的顶点坐标为准。
for(pC=CT,i=0; i<NUM; i++,pC++)
{
p->xy=10000L*(pC->x )+(pC->y );p->No=1;p++;
p->xy=10000L*(pC->x-1)+(pC->y );p->No=2;p++;
p->xy=10000L*(pC->x-1)+(pC->y-1);p->No=4;p++;
p->xy=10000L*(pC->x )+(pC->y-1);p->No=8;p++;
}
//STEP 3:
//释放动态数组CT[]使用的内存。
free(CT);
//STEP 4:
//写出4种不同覆盖情况下的面积。
//⑴未被“他人”遮盖,此时面积=π/4
area[1]=Pi/4;
//⑵被单位间隔的左、右、上、下“邻居”之一覆盖
// 面积=边长为1的等边△+2*圆心角为30度的扇形
area[2]=0.5*sin(Pi/3)+2*(Pi/12);
//⑶被间隔为√2的斜线方向的某个“邻居”所覆盖,此时面积=1
//⑷上述两种情况的叠加,此时面积=1
area[3]=area[4]=1;
//STEP 5:
//下面进行最困难的一步——覆盖度统计。
//对数组QT[j]中的xy成员进行排序(冒泡)
for(i=1;i<=4*NUM-1;i++)
for(j=1;j<=4*NUM-i;j++)
if(QT[j-1].xy>QT[j].xy)
{ temp=QT[j-1];
QT[j-1]=QT[j];
QT[j]=temp;
}
//至此有相同参考点(x,y)的
//1/4圆就彼此"挨"得很近了
//下面要统计覆盖度啦:
temp=QT[0];
for(i=j=0;j<4*NUM;j++,i++)
{
while(temp.xy==QT[j].xy)
temp.No|=QT[j++].No;//按位"或"
QT[i]=temp;//i相当于"写指针"
temp=QT[j];
}
//STEP 6:
//计算NUM个圆总的占地面积。
for(j=0;j<=i;j++)
sum+=Area(&QT[j]);
printf("total area = %lf\n",sum);
free(QT);
return 0;
}