问题 A: Birthday Cake
时间限制: 1 Sec 内存限制: 128 MB
提交: 88 解决: 14
[提交] [状态] [命题人:admin]题目描述
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 n pieces so that each piece has exactly one candle on it, and there are no left-over pieces. For that, he made m 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). The candles are nn distinct points located strictly inside the circle. Each cut is a straight line ax+by+c=0, described by three coefficients a, b, and c.
输入
Input starts with three integers n (1 ≤ n ≤ 50), m (1 ≤ m ≤ 15), and r (1 ≤ r ≤ 100) on the first line.
The next n lines give the locations of the candles. Each line has two integers x and y giving the coordinates of one candle .
The next m lines give the coefficients of the cutting lines. Each line has three integers a, b, and c (0 ≤ |a|, |b| ≤ 100, 0 ≤ |c| ≤ 20 000) describing a line of the form ax + by + c = 0. The values a and b 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−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−4 in any direction.
输出
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”.
样例输入
复制样例数据
4 2 3 0 1 1 0 -1 0 0 -1 -1 1 0 2 1 0样例输出
yes
感觉非常简单 ,一刀下去,一定把蜡烛给分成俩集合,
这一个集合中的任意一个和另一个集合里的任意一个都没关系了(被切开)
只要最后每个蜡烛只能自己和自己有关系即可,
然后我就wa了,然后忽然想起来,这样写块分多了就gg了(有的块里没蜡烛)
于是有一个平面的欧拉公式(最后我没想起来)
V-E+F = 2
V是点数,E是边数,F是面数(也就是这里的块数),考虑在圆形中,所以
V-E+F=1
易知F = n
V是园内交点数,易知对于每一条直线来说,如果有k个交点,会被分成k+1条边
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e2+7;
pair<int,int> A[maxn];
int a[maxn],b[maxn],c[maxn];
bool vis[maxn][maxn];
int n,m,r;
int main(){
int flag = 1;
for(int i=0;i<maxn;i++)for(int j=0;j<maxn;j++)vis[i][j] = 1;
scanf("%d%d%d",&n,&m,&r);
for(int i=0;i<n;i++)scanf("%d%d",&A[i].first,&A[i].second);
for(int i=0;i<m;i++){
bool t[maxn] = {0};
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int j=0;j<n;j++)if(a[i]*A[j].first+b[i]*A[j].second+c[i]<0)t[j] = 1;
for(int j=0;j<n;j++)if(t[j])// t[j] == 1
for(int k=0;k<n;k++)if(!t[k])// t[k] == 0
vis[j][k] = vis[k][j] = 0;
}
for(int i=0;i<n;i++){
int cnt = 0;
for(int j=0;j<n;j++)if(vis[i][j])cnt++;
if(cnt>1)return 0*puts("no");
}
int V = 0,E = 0;
for(int i=0;i<m;i++){
int cnt = 0;//a line will be cross cnt string
for(int j=0;j<m;j++)if(i!=j){
if(a[i]*b[j] == a[j]*b[i])continue;
double y = -1.0*(a[j]*c[i]-a[i]*c[j])/(a[j]*b[i]-a[i]*b[j]);
double x = 1.0*(b[i]*c[j]-b[j]*c[i])/(a[i]*b[j]-a[j]*b[i]);;
if(x*x+y*y<r*r)cnt++;
}
V += cnt;
E += cnt+1;
}
V /= 2;
if(V-E+n != 1)return 0*puts("no");
puts("yes");
return 0;
}