Finding Lines
题目大意:给你n个点和一个概率,再给出n个坐标,问任意两点构成的直线,这条直线包含的点的个数比上n大于等于这个概率就输出possible,否则输出impossible。
解题思路:n的范围是10的5次方,时间是20000毫秒,暴力枚举的时间复杂度是O(n^3),最大是10的15次方。所以枚举存在问题。于是就采用随机枚举的办法,写个随机数生产器,随机出1000(也可以是500,10000,都能过)个数来作为直线生成的点,枚举所有的点有几个在这直线上。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <time.h>
#include <stdlib.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int Max = 100100;
typedef long long LL;
int x[Max], y[Max];
bool judge(int i, int a, int b)
{
int x1, x2, x3, y1, y2, y3;
x1 = x[i];
x2 = x[a];
x3 = x[b];
y1 = y[i];
y2 = y[a];
y3 = y[b];
if((y2-y1)*(x3-x1)==(y3-y1)*(x2-x1))
return 1;
else
return 0;
}
int main()
{
int n, k, i, j, d, s1, s2;
double m;
while(cin>>n>>m)
{
int num = 1000;
for(i = 0; i < n; i++)
{
scanf("%d %d", &x[i], &y[i]);
}
if(n == 1 || n == 2)
{
printf("possible\n");
continue;
}
srand(time(0));
int flag = 0;
while(num--)
{
s1 = 0;
s2 = 0;
while(s1 == s2)
{
s1 = rand()%n;
s2 = rand()%n;
}
//printf("%d %d\n", s1, s2);
int sum = 0;
for(i = 0; i < n; i++)
{
if(judge(i, s1, s2))
{
sum++;
}
}
//cout<<sum<<endl;
if(100.0*sum/n >= m)
{
flag = 1;
break;
}
}
if(flag == 1)
printf("possible\n");
else
printf("impossible\n");
}
return 0;
}