Accept: 443 Submit: 1536 Special Judge
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Given an integer N, your task is to judge whether there exist N points in the plane such that satisfy the following conditions:
1. The distance between any two points is no greater than 1.0.
2. The distance between any point and the origin (0,0) is no greater than 1.0.
3. There are exactly N pairs of the points that their distance is exactly 1.0.
4. The area of the convex hull constituted by these N points is no less than 0.5.
5. The area of the convex hull constituted by these N points is no greater than 0.75.
Input
The first line of the date is an integer T, which is the number of the text cases.
Then T cases follow, each contains an integer N described above.
1 <= T <= 100, 1 <= N <= 100
Output
For each case, output “Yes” if this kind of set of points exists, then output N lines described these N points with its coordinate. Make true that each coordinate of your output should be a real number with AT MOST 6 digits after decimal point.
Your answer will be accepted if your absolute error for each number is no more than 10-4.
Otherwise just output “No”.
See the sample input and output for more details.
Sample Input
Sample Output
Hint
This problem is special judge.
题意:
要求满足下面四个条件的n个点的坐标:
1.任意两点之间的距离不超过1.0。
2.所有点距原点 O(0,0) 的距离不超过1。
3.有 n 对点之间的距离为 1.0。
4.n个点所围成的图形面积不低于0.5。
5.n个点所围成的图形面积不超过0.75。
题目链接: Forever 0.5
解题思路:
看了别人题解的体会,觉得想法值得学习!
为了满足第2个条件,可以以O点(0,0) 建立一个圆,那么所有满足其他条件的点,都必须在圆内。
通过分析知道3个点所能围成的面积最多为 sqrt(3) / 4 < 0.5,即一个边长为 1 的等边三角形,所以要符合条件,n > 3。
考虑四个点,为满足 条件3 ,选取O(0,0),A(1,0),B(0.5,1 - sqrt( 0.5 ^ 2 ) ),C(0.5, - sqrt( 0.5 ^ 2 ) ),
O,A点不难分析,易知OAB为等边三角形,所以B 在 OA的垂直平分线上,即横坐标为 0.5,而满足OB=1,的点必须在圆x^2 + y^2 = 1上,所以B的纵坐标为 1 - sqrt( 0.5 ^ 2 )。
而加入第4个点C时,此时已经有三条边满足 条件3 ,那么只需要在作出一条 满足 条件3 的边即可,此时已经确定了C点坐标(因为OB最远)。
选了这四个点,不难得出此时面积 S(OABC) = S(OBC) + S(ABC) = 1/2 *1 * 1/2 +1/2 * 1 *1/2=0.5,满足条件4,5。
此后,每个加入的点需要满足 多了一条长度为 1 的边,新图形总面积不超过0.75,与其他点的距离不超过1。
为满足多一条长度为1的边可选 圆上一点 D,因为OD = 1,扇形OAB的面积为 0.5 < 3.14/6 < 0.75,因此可以任意选取弧AB间任意点D,与已有点的最远距离肯定是 OD =1,与C点距离可以通过分析 D在CB = 1 的下方,所以CD < 1,同理可分析A点,如此一来枚举弧AB上的点的 y 坐标即可,然后通过圆上的方程求出横坐标x。
代码:
#include<cstdio>
#include<iostream>
#include<map>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
#define si(x) scanf("%d",&x);
#define sii(x,y) scanf("%d%d",&x,&y);
#define siii(x,y,z) scanf("%d%d%d",&x,&y,&z);
#define rep(i,s,n) for(i = s;i <= n;i++)
#define dow(i,n,s) for(i = n;i >= s;i--)
using namespace std;
typedef long long LL;
const double t = 0.005;
double x[105],y[105];
void table()
{
int i;
x[1] = y[1] = 0; // O点
x[2] = 1.0, y[2] = 0; //A点
x[3] = 0.5, y[3] = sqrt(1 - 0.25); //B点
x[4] = 0.5, y[4] = y[3] - 1; // C点
rep(i,5,102) { //通过OABC四边形,寻找其他的点
y[i] = i * t;
x[i] = sqrt(1 - y[i] * y[i]); //圆上的点满足圆的方程
}
}
int main()
{
int T,n,i;
table();
si(T);
while(T--) {
si(n);
if(n <= 3) printf("No\n");
else {
printf("Yes\n");
rep(i,1,n) {
printf("%.6f %.6f\n",y[i],x[i]);
}
}
}
return 0;
}