A - Birthday Cake
https://open.kattis.com/problems/birthdaycake
On his birthday, John’s parents made him a huge birthday cake! Everyone had a wonderful dinner, and now it’s time to eat the cake. There are nn candles on the cake. John wants to divide the cake into nn pieces so that each piece has exactly one candle on it, and there are no left-over pieces. For that, he made mm cuts across the cake. Could you help check if John’s cuts successfully divide the candles on the cake?
Formally, the cake is a circle of radius rr centered at (0,0)(0,0). The candles are nndistinct points located strictly inside the circle. Each cut is a straight line ax+by+c=0ax+by+c=0, described by three coefficients aa, bb, and cc.
Input
Input starts with three integers nn (1≤n≤501≤n≤50), mm (1≤m≤151≤m≤15), and rr (1≤r≤1001≤r≤100) on the first line.
The next nn lines give the locations of the candles. Each line has two integers xx and yy giving the coordinates of one candle (0≤x2+y2−−−−−−√<r0≤x2+y2<r).
The next mm lines give the coefficients of the cutting lines. Each line has three integers aa, bb, and cc (0≤|a|,|b|≤100,0≤|c|≤200000≤|a|,|b|≤100,0≤|c|≤20000) describing a line of the form ax+by+c=0ax+by+c=0. The values aa and bb are not both zero.
All candles and lines are distinct. No candle is on a cut line. No line is completely outside or tangent to the cake. The input guarantees that the number of cake pieces remains the same if any cut line is shifted by at most 10−410−4 in any direction. The input also guarantees that each candle remains in the interior of the same piece of cake if its position is shifted by at most 10−410−4 in any direction.
Output
Output “yes” if John’s cuts successfully divide the cake so that each piece he obtains has exactly one candle on it. Otherwise, output “no”.
Sample Input 1 | Sample Output 1 |
---|---|
| |
Sample Input 2 | Sample Output 2 |
---|---|
| |
Sample Input 3 | Sample Output 3 |
---|---|
| |
Sample Input 4 | Sample Output 4 |
---|---|
| |
题意:给出一个蛋糕 即圆心为(0,0)半径为 r 的一个圆,上面有 n 块糖果 ( x , y ) 为糖果点的坐标 ,切 m 刀 直线方程 ax+by+c,问是否能恰好将这 n 块糖果分在 n 个不同的区域上
我们可以先判断糖果是否是在不同的区域上,然后再判断区域数是否是 n。
先行知识:
1.把点(x,y)带入直线方程ax+by+c,有三种状态>0,=0,<0,可以判断点在直线的左边,线上,右边三种状态。
只要有一条线使两个点在这条线的不同侧,这两个点就已经在不同区域
2.圆内的点、边、区域数的关系 v + e + 1 = n,v是交点数,e为边数,n是区域数
3.一般式方程两直线相交,a1*b2! = a2b1,如果相等的话a1*b2 == a2b1,即a1/a2 = b1/b2两直线平行
两直线交点:
x = (b1*c2-b2*c1)/D
y = (c1*a2-c2*a1)/D
D = a0*b1 – a1*b0, (D为0时,表示两直线重合)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <set>
using namespace std;
const int maxn = 100 + 7 ;
typedef pair<double,double> point;//直线的交点
bool k[maxn][maxn];//判断点i在直线j的哪一侧
struct Point
{
int x,y;
}p[maxn];
struct Line
{
int a,b,c;
}l[maxn];
int main()
{
int n,m,r;
cin>>n>>m>>r;
for(int i=1;i<=n;i++)
cin>>p[i].x>>p[i].y;
for(int i=1;i<=m;i++)
cin>>l[i].a>>l[i].b>>l[i].c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(p[i].x*l[j].a+p[i].y*l[j].b+l[j].c>0)
k[i][j] = true;//点在线的哪一侧,不能在直线上
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
continue;
bool flag = false;
for(int h=1;h<=m;h++)
{
if(k[i][h]!=k[j][h])//只要有一条线使两个点在不同侧 就已经在不同区域
{
flag = true;
break;
}
}
if(!flag)
{
cout<<"no"<<endl;
return 0;
}
}
}
set<point>pp;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
if(i==j)
continue;
int a1=l[i].a,b1=l[i].b,c1=l[i].c;
int a2=l[j].a,b2=l[j].b,c2=l[j].c;
double d=a1*b2-a2*b1;
if(a2*b1-a1*b2!=0)//两直线相交
{
double x = 1.0*(b1*c2-b2*c1)/d;
double y = 1.0*(c1*a2-c2*a1)/d;
if(x*x+y*y<r*r)//圆心(0,0),如果交点在圆内
pp.insert(point(x,y));//防止交点重复 去重
}
}
}
if(pp.size()+m+1==n) //V+E+1=N 区域数是否为n
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}