C. 学姐的学弟 2014新生暑假个人排位赛01
时间限制 1000 ms
内存限制 65536 KB
题目描述
学姐正在写作业,但是她写着写着就开始想学弟,走神的她就开始在纸上画圈圈。这时学弟突然出现了,好奇的学弟问学姐在做什么,惊慌之下,学姐随口说想算一下这些圆覆盖的面积为多少。学弟顿时非常仰慕学姐,但是学姐突然意识到自己不会做,为了自己能给学弟留下好印象,她来求助你帮她算出来这些圆覆盖的面积。
为了简化问题,我们假设所有圆的半径都为1。
输入格式
输入有多组数据。开头为一个整数 T(T≤10) ,表示数据组数,接下来T组输入,每组开头为一个整数 n(1≤n≤100) ,表示学姐画的圆的个数,接下来 n 行,每行两个整数 xi,yi ,表示圆的圆心坐标, 1≤xi,yi≤100 。
输出格式
输出一个数,表示面积并,精确到小数点后五位。
输入样例
1
2
1 1
2 1
输出样例
5.05482
赛中提交:NULL
赛后ac:Y
题目大意:画很多单位圆,求最后这些圆覆盖的面积
思路:
可以建立一个网格坐标,而这些圆重叠部分的情况只有两种,
对边重叠和对角重叠,
也就对应了网格的四种状态,全覆盖,对边覆盖,对角覆盖,四分之一π
一下是AC代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#define Pi 3.141592654
#define maxn 100100
using namespace std;
typedef pair<int,int> P;
double siz[200][200],ep1,ep2;
int N;
bool used[200][200];
P A[150];
double res;
int dx[4]={0,1,0,1},dy[4]={0,0,1,1};
void solve()
{
int i,j,k;
res=0;
int dX[4]={-1,0,-1,0},dY[4]={-1,-1,0,0};
/* for(i=0;i<4;i++)printf("%d ",dX[i]);
printf("\n");*/
res=0;
for(i=0;i<N;i++){
for(j=0;j<4;j++){
int x=A[i].first+dx[j];
int y=A[i].second+dy[j];
if(siz[x][y]<1e-7){
if((used[x][y]&&used[x-1][y-1])||(used[x-1][y]&&used[x][y-1])){
siz[x][y]=1;
}
else{
int flag=0;
for(k=0;k<4;k++){
if(used[x+dX[k]][y+dY[k]]){
flag++;
}
}
if(flag==1)siz[x][y]=ep2;
else{
siz[x][y]=ep1;
}
}
res+=siz[x][y];
}
}
}
}
int main()
{
int i,j,T;
ep2=Pi/4;
ep1=Pi/6+sqrt(3)/4;
scanf("%d",&T);
while(T--){
memset(siz,0,sizeof(siz));
memset(used,0,sizeof(used));
scanf("%d",&N);
for(i=0;i<N;i++){
scanf("%d %d",&A[i].first,&A[i].second);
used[A[i].first][A[i].second]=true;
}
solve();
printf("%.5lf\n",res);
}
return 0;
}