问题 A: Birthday Cake

问题 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;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值