UVALive6955:Finding Lines(直线过点 & 随机算法)

UVALive6955:Finding Lines(直线过点 & 随机算法)_第1张图片UVALive6955:Finding Lines(直线过点 & 随机算法)_第2张图片

题意:给N个点,和数字p,问是否至少有p%个点在同一条直线上。

思路:循环280次枚举任意两个点,O(n)验证这两个点是否在线上,因为若这条直线存在,最坏情况选错的概率仅为(1-p*p)^280 = 0.96^280。

# include 
# include 
# include 
# include 
using namespace std;
typedef long long LL;
const int maxn = 1e5+30;
int n, m, p;
struct node
{
    LL x, y;
}a[maxn];
LL cross(node n1, node n2, node n3)
{
    return (n2.x-n1.x) * (n3.y-n1.y) - (n2.y-n1.y) * (n3.x-n1.x);
}
bool cal(node n1, node n2)
{
    int ret = 0;
    for(int i=1; i<=n; ++i)
    {
        if(!cross(n1, n2, a[i])) ++ret;
        if(ret >= m) return true;
    }
    return false;
}
int main()
{
    srand(time(0));
    while(~scanf("%d%d",&n,&p))
    {
        for(int i=1; i<=n; ++i) scanf("%lld%lld",&a[i].x,&a[i].y);
        if(n == 1)
        {
            puts("possible");
            continue;
        }
        m = (n*p + 99)/100;
        int x, y, f=0;
        for(int i=1; i<=280; ++i)
        {
            x = rand()*rand()%n + 1;
            y = rand()*rand()%n + 1;
            while(x == y) y = rand()*rand()%n + 1;
            if(cal(a[x], a[y]))
            {
                f = 1;
                break;
            }
        }
        if(f) puts("possible");
        else puts("impossible");
    }
    return 0;
}


你可能感兴趣的:(计算几何)