专栏文章
题解:P14433 [JOISC 2013] JOI 海报 / JOI Poster
P14433题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minc28ic
- 此快照首次捕获于
- 2025/12/01 23:57 3 个月前
- 此快照最后确认于
- 2025/12/01 23:57 3 个月前
思路:
由于 ,数据范围非常小,所以这道题可以直接愉快地四层循环枚举四个点 。
设:
- 为点 与点 的距离。
- ,以点 为圆心、点 为圆上点。
- ,以点 为圆心、点 为圆上点。
- 为圆心的坐标。
发现:
-
要使小圆被大圆完全包含,则:。
-
要使圆心到矩形边界的最小距离必须不小于半径,则:。
于是,思路就很明确了:
- 枚举四个点 ;
- 计算出半径 、;
- 判断两个圆是否都在海报内;
- 如果 ,则计数。
注意:
注意浮点数计算要加上微小容差,以避免精度误差。
Code
CPP#include<bits/stdc++.h>
using namespace std ;
const double f=1e-9;//微小容差
struct node {
double x,y;
};
vector<node> s;
int n;
double w,h;
double dis (node a,node b) {
double dx=a.x-b.x,dy=a.y-b.y;
return sqrt(dx*dx+dy*dy);
}
bool check(node a,double r,double w,double h) {
return (r<=a.x)&&(r<=a.y)&&(r<=w-a.x)&&(r<=h-a.y);
}
int main () {
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>w>>h;
for (int i=0;i<n;i++) {
double x,y;
cin>>x>>y;
s.push_back({x,y});
}
long long ans=0;
for (int i=0;i<n;i++) {
for (int j=0;j<n;j++) {
if (i==j) continue;
double r1=dis(s[i],s[j]);
if (!check(s[i],r1,w,h)) continue;
for (int k=0;k<n;k++) {
if (k==i||k==j) continue;
for (int l=0;l<n;l++) {
if (l==i||l==j||l==k) continue;
double r2=dis(s[k],s[l]);
if (!check(s[k],r2,w,h)) continue;
double ACdis=dis(s[i],s[k]);
if (ACdis+r2+f<r1) ans++;
}
}
}
}
cout<<ans;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...